代码分割(Code Splitting)

代码分割(Code Splitting)

  • 为什么要分割代码?代码分割有什么作用呢?
    答:两个方面。
    1、项目包含第三方依赖库以及自己写的代码,打包出的文件会比较大,在用户访问系统的时候,由于请求的资源比较大,所以会响应的比较慢,造成页面渲染缓慢,影响用户体验。

    代码分割以后,chunk会相应的变小,用户访问时,只需返回此页面相关chunk,再加上浏览器的并行请求策略,从而加快系统响应速度,优化用户体验。

    2、由于将第三方依赖库和自己写的代码打包到了一起,一旦我们修改了其中的一部分代码,整个chunk(包括第三方依赖库,即使它没有发生任何变化)都会重新打包,生成带有新的hash值的chunk。原本在浏览器已经缓存了的chunk,会因为hash的变更,不会再使用之前缓存的chunk,而重新请求新的chunk。简言之,一处代码变更,要重新请求所有资源,缓存效果差。

    代码分割以后,就可以将比较大的第三方依赖库分离到单独的chunk中,以后即使用户修改业务代码,只要不改变此库的版本或库代码,在浏览器端的此chunk的缓存会一直有效。剩余的比较小的第三方依赖库打包到同一个chunk中,将依赖库与业务代码彻底分离。由于更改依赖库的版本的概率比较小,所以可以有效利用缓存,提升响应速度。

一、SplitChunksPlugin

将公共的依赖模块提取到已有的入口 chunk 中,或者提取到一个新生成的 chunk。

项目代码中第三方依赖库变动较少,只有在变更第三方依赖库版本的时候才会产生变化。所以我们有必要将比较大的第三方依赖库分离到独立的chunk中,当用户首次请求资源时,会将资源缓存,以后再次访问此资源时,就可以直接使用缓存,提升响应速度。
如果此chunk内容发生变更,打包后它的文件名hash值会发生变化,用户访问网页时,会首先返回html,html中包含了访问此网页需要的新的资源地址,从而请求新的chunk,然后将新的chunk缓存。

配置: 请参考 官方文档.
示例:

// vue.config.js  chainWebpack
config.optimization.splitChunks({
        chunks: 'all',
        cacheGroups: {
          libs: {
            name: 'chunk-libs',
            test: /[\\/]node_modules[\\/]/,
            priority: 10,
            chunks: 'initial',
            enforce: true
          },
          lodash: {
            name: 'chunk-lodash',
            priority: 11,
            test: /[\\/]node_modules[\\/]lodash[\\/]/
          },
          elementUI: {
            name: 'chunk-elementUI',
            priority: 12,
            test: /[\\/]node_modules[\\/]_?element-ui(.*)[\\/]/
          }
        }
      })

二、组件按组分块

有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中,只需要使用 命名 chunk (opens new window),一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。
打包生成的文件名为:[chunkName].[ hash].[ext] 组成

配置:

// router.js
// 最后生成的文件名:group-foo.[hash].[ext]
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')

参考:官方文档.