webpack之optimization.runtimeChunk作用

runtimeChunk,直观翻译是运行时的chunk文件,其作用是啥呢,通过调研了解了一波,在此记录下。

何为运行时代码?

形如import('abc').then(res=>{})这种异步加载的代码,在webpack中即为运行时代码。
在VueCli工程中常见的异步加载路由即为runtime代码。

{
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
    // component: About
  }

搭建工程测试功效

1、搭建简单的vue项目,使用vuecli新建一个只需要router的项目,脚手架默认路由配置了一个异步加载的about路由,如上图所示

2、不设置runtimeChunk时,查看打包文件,此时不需要做任何操作,因为其默认是false,直接yarn build,此时生成的主代码文件的hash值为7d50fa23

image.png

3、接着改变about.vue文件的内容,再次build,查看打包结果,发现app文件的hash值发生了变化。


发现app文件的hash值发生了变化。

设置runtimeChunk是将包含chunks 映射关系的 list单独从 app.js里提取出来,因为每一个 chunk 的 id 基本都是基于内容 hash 出来的,所以每次改动都会影响它,如果不将它提取出来的话,等于app.js每次都会改变。缓存就失效了。设置runtimeChunk之后,webpack就会生成一个个runtime~xxx.js的文件。
然后每次更改所谓的运行时代码文件时,打包构建时app.js的hash值是不会改变的。如果每次项目更新都会更改app.js的hash值,那么用户端浏览器每次都需要重新加载变化的app.js,如果项目大切优化分包没做好的话会导致第一次加载很耗时,导致用户体验变差。现在设置了runtimeChunk,就解决了这样的问题。所以这样做的目的是避免文件的频繁变更导致浏览器缓存失效,所以其是更好的利用缓存。提升用户体验。

4、新建vue.config.js,配置runtimeChunk,第一次打包,然后修改about,在打包一次,查看2次打包之后app文件的hash值的变化。

// vue.config.js
module.exports = {
  productionSourceMap: false,
  configureWebpack: {
     runtimeChunk: true
  }
}
image.png

通过截图看到2次打包生成的app文件的hash值没有改变。和上面说的作用一致。

你以为这就完了?

1、查看下runtime~xxx.js文件内容:

function a(e){return i.p+"js/"+({about:"about"}[e]||e)+"."+{about:"3cc6fa76"}[e]+".js"}f

发现文件很小,且就是加载chunk的依赖关系的文件。虽然每次构建后app的hash没有改变,但是runtime~xxx.js会变啊。每次重新构建上线后,浏览器每次都需要重新请求它,它的 http 耗时远大于它的执行时间了,所以建议不要将它单独拆包,而是将它内联到我们的 index.html 之中。这边我们使用script-ext-html-webpack-plugin来实现。(也可使用html-webpack-inline-source-plugin,其不会删除runtime文件。)

// vue.config.js
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
module.exports = {
  productionSourceMap: false,
  configureWebpack: {
    optimization: {
      runtimeChunk: true
    },
    plugins: [
      new ScriptExtHtmlWebpackPlugin({
        inline: /runtime~.+\.js$/  //正则匹配runtime文件名
      })
    ]
  },
  chainWebpack: config => {
    config.plugin('preload')
      .tap(args => {
        args[0].fileBlacklist.push(/runtime~.+\.js$/) //正则匹配runtime文件名,去除该文件的preload
        return args
      })
  }
}

重新打包,查看index.html文件





    
    
    
    
    runtime-chunk
    
    
    
    



    

index.html中已经没有对runtime~xxx.js的引用了,而是直接将其代码写入到了index.html中,故不会在请求文件,减少http请求。

总结

runtimeChunk作用是为了线上更新版本时,充分利用浏览器缓存,使用户感知的影响到最低。

资料鉴于:https://developers.google.com/web/fundamentals/performance/webpack/use-long-term-caching
https://segmentfault.com/a/1190000015919928#articleHeader4

你可能感兴趣的:(webpack之optimization.runtimeChunk作用)