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.js和vendors.js以外,就是各个页面各自打包生成的文件。在此,我们以p_Solutions_edit这个页面为例,只需要关注umi.jsp_Solutions_edit.js

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

 我们惊讶地发现,除了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.js不必要的更新?

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

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

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

请看umi具体配置:

javascript 复制代码
  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

验证效果

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

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

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

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

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

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

相关推荐
IT_陈寒8 小时前
Java的finally块竟然不是你想的那个finally!
前端·人工智能·后端
2501_940041748 小时前
挖掘前端交互潜力的五款创意游戏原型
前端·游戏
C+-C资深大佬8 小时前
变量作用域(通俗 + 清晰讲解,适合编程入门)
前端·javascript·vue.js
weelinking8 小时前
【claude】15_Claude使用经验与最佳实践
前端·人工智能·python·sql·数据挖掘·前端框架·github
XS0301068 小时前
HTML 入门教程
前端·html
弹简特8 小时前
【Vue3速成】02-vue工程化目录结构+执行原理
前端·vue.js·npm
杖雍皓8 小时前
Markstream-VUE:构建高性能流式 Markdown 渲染器
前端·javascript·vue.js·markdown·流式输出
ZC跨境爬虫8 小时前
模块化烹饪小程序开发日记 Day6:(菜谱列表接口开发与日志调试实践)
前端·javascript·css·ui·微信小程序·html
KaMeidebaby8 小时前
卡梅德生物技术快报|适配体筛选技术架构演进:SPARK-seq 高通量平台原理与技术流程解析
大数据·前端·其他·百度·架构·spark·新浪微博