umi项目配置runtimeChunk优化缓存实践

runtimeChunk是什么?

 webpack在打包的过程会生成runtime和manifest代码。runtime和manifest,在webpack配置中统一通过optimization.runtimeChunk配置。

runtime:在浏览器运行过程中,webpack用来连接模块之间的代码。比如,已经加载到浏览器中的连接模块逻辑、尚未加载模块的延迟加载逻辑。

manifest:是一个json / json文件,它包含了每个模块的唯一标识符 (模块id),以及模块对应的文件在输出目录中的位置 之间的映射关系,用于帮助webpack快速地查找、加载所需的模块。

 默认情况下,runtime和manifest并不会打包成单独的代码块。而嵌入在入口chunk中。在umi项目中,它就是在嵌入在umi.js中。

为什么要配置optimization.runtimeChunk?

 先简要地概括下,在umi项目开启了dynamicImport时,通过配置optimization.runtimeChunkruntime和manifest抽离成单独的代码块,对应用的缓存效率有帮助。

 具体细节,请看以下分析:

默认配置打包存在的问题

  • 未配置optimization.runtimeChunk,默认webpack配置的打包结果:

umi项目配置runtimeChunk优化缓存实践

 可以看到,除了umi.js和vendors.js以外,就是各个页面各自打包生成的文件。在此,我们以p_Solutions_edit这个页面为例,只需要关注umi.jsp_Solutions_edit.js

  • 现在,我们对p_Solutions_edit页面进行一些修改,比如添加一个console.log('test')并重新打包,打包结果如下:

umi项目配置runtimeChunk优化缓存实践
 我们惊讶地发现,除了p_Solutions_edit.js的hash更新了以外,umi.js的hash竟然也发生了更新。

这意味着,每当我们改动任何一个页面中的一丁点代码,并将其发布上线之后,用户打开页面不仅需要重新下载该页面对应的js文件,还需要重新下载整个umi.js文件。

 这对于用户实际上是没有必要的,因为umi.js只包含了antd等node_modules目录下的依赖和项目代码中一些公共目录的代码。这些依赖和代码并没有改动,完全可以直接使用用户之前缓存的umi.js (如果用户非首次访问的话)。

 而且,一般umi.js都比较大,我自己的项目里,打包且压缩后的umi.js有接近1MB。

为什么umi.js的hash值也会更新?

 其实,umi.js的hash发生更新的罪魁祸首就是我们之前说的runtime和manifest。默认情况下,它俩就嵌入在umi.js里。它们保存着本次打包生成的所有文件的路径,当然路径里也包含文件的hash。所以,一旦p_Solutions_edit页面的代码有更新,打包生成的p_Solutions_edit.js的hash更新,runtime和manifest就也要更新。

 所以才导致了我们明明没有改动umi.js相关的代码,它的hash却发生了更新。

 举个栗子:第二次打包生成的umi.js中保存的文件hash:

umi项目配置runtimeChunk优化缓存实践

如何避免umi.js不必要的更新?

 其实也简单,我们如果可以把runtime和manifest提取成单独的代码块,不要嵌入在umi.js里,不就可以了么?

那么如何实现从入口chunk中抽离runtime和manifest呢?

 在单页面应用中,webpack的配置,optimization.runtimeChunk: true,可以实现抽离单独的runtime和manifest

 请看umi具体配置:

  chunks: ['runtime~umi', 'vendors', 'umi'],   //todo
  chainWebpack: function (config, { webpack }) {
    config.merge({
      optimization: {
        minimize: process.env.NODE_ENV === 'production',
        splitChunks: {
          chunks: 'all',
          minSize: 30000,
          minChunks: 2,
          automaticNameDelimiter: '.',
          cacheGroups: {
            vendors: {
              name: 'vendors',
              test: /[\/]node_modules[\/]/,
              priority: 10,
            }
          },
        },
        runtimeChunk: true   //todo
      },
    });
  },

 注意:
1. 请务必在chunks中添加'runtime~umi'chunks里配置的是应用初始加载就需要的代码块,runtime和manifest肯定需要,不然你的umi应用会一直loading,打不开页面。
2. splitChunks是我自己的配置,如果不需要拆包,可以不配。没有splitChunks的话,记得删掉chunks数组里的vendors

验证效果

  • 添加以上配置之后,我们先打一次包,本次打包结果如下:

umi项目配置runtimeChunk优化缓存实践

 可以看到,本次打包比以往多了一个文件,runtime~umi.[hash].js,这就是我们抽离出的单独的runtime和manifest。

  • 修改p_Solutions_edit页面,再次打包,请对比umi.jsp_Solutions_edit.js的hash:

umi项目配置runtimeChunk优化缓存实践

 可以看出umi.js的hash保持没变,只有p_Solutions_edit.js的hash有更新。runtime~umi.js的hash也会更新。

 这样,就避免了代码发布后,用户再次打开页面,需要重新下载umi.js的问题,可以直接使用缓存的资源文件,以提升加载页面的速度。

如果这篇博客对你有帮助,麻烦点个赞~

原文链接:https://juejin.cn/post/7327138554756137012 作者:我人很好

(0)
上一篇 2024年1月24日 上午10:05
下一篇 2024年1月24日 上午10:16

相关推荐

发表回复

登录后才能评论