最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • webpack4 之 cacheGroups 分包【究极奥义】

    正文概述 掘金(掘金安东尼)   2021-01-20   445

    近来遇项目打包之事,撰文记之。以期分享,皆有所获。

    前提

    前提有两点,需要得到你的认同:

    1. 【后台管理系统】框架和 UI 组件库最强组合为 vue-element-admin + Element UI!(●'◡'●)

    2. webpack4 最核心的特性是 【splitChunks】,splitChunks 最核心的配置是 cacheGroups!

    基于这个两个前提,我们再进行下一步。

    分析工具

    webpack 打包分析有它就够了:webpack-bundle-analyzer

    • 安装
    npm install --save-dev webpack-bundle-analyzer
    
    • 配置:因为 vue-element-admin 基于 vueCli4,所以在 vue.config.js chainWebpack 中设置
     config.plugin('BundleAnalyzerPlugin').use(BundleAnalyzerPlugin).tap(() => [
          {
            rel: 'BundleAnalyzerPlugin',
            analyzerMode: 'server', // 'server': 启动端口服务;'static': 生成 report.html;'disabled': 配合 generateStatsFile 使用;
            generateStatsFile: false, // 是否生成stats.json文件
            analyzerHost: '127.0.0.1',
            analyzerPort: '8877',
            reportFilename: 'report.html',
            defaultSizes: 'parsed',
            openAnalyzer: false,
            statsFilename: 'stats.json',
            statsOptions: null,
            excludeAssets: null
          }
    

    其中 analyzerMode 的设置比较重要。

    • 运行:
    npm run dev 或 npm run build
    
    • 访问:
    http://127.0.0.1:8877
    

    现状问题

    看一下咱们的打包分析图:

    webpack4 之 cacheGroups 分包【究极奥义】

    得出如上图的分包并不难,vue-element-admin 自带这些配置。

    config.optimization.splitChunks({
            chunks: 'all',
            cacheGroups: {
              libs: {
                name: 'chunk-libs',
                test: /[\\/]node_modules[\\/]/,
                priority: 10,
                chunks: 'initial' // only package third parties that are initially dependent
              },
              elementUI: {
                name: 'chunk-elementUI', // split elementUI into a single package
                priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
              },
              commons: {
                name: 'chunk-commons',
                test: resolve('src/components'), // can customize your rules
                minChunks: 3, //  minimum common number
                priority: 5,
                reuseExistingChunk: true
              }
            }
          })
    

    如果你暂时还看不懂这些配置项,先别急,后面会一一陈述。

    你只用先知道:它拆了初始化加载的第三方包、拆了 Element UI 库、拆了 src/components。

    一切似乎好像还不错,但是我们并不满足。

    实际上,咱们跑一下 npm run build:test 也会报警告。

    webpack4 之 cacheGroups 分包【究极奥义】

    那么还有哪些点可以继续优化?结合以上分析图和 test warning,很明显,我们需要思考:

    1. Echarts 的体积大小不能忽视,如何处理它?是首页加载还是异步加载?要按需引入吗?
    2. vue.js 等库还能不能再拆?
    3. 首页 Entrypoints 所依赖的包还能不能再优化?
    4. 包的体积应控制在什么范围?包太大,加载会太慢!包太小,会消耗 HTTP 请求连接!更多:合并 HTTP 请求是否真的有意义?
    5. 更多......

    淦!打包什么的,多打几遍就完事了。十遍不行就一百遍,一百遍不行就一千遍,一千遍不行就......

    优化的结果

    淦完后得出如下打包分析图:

    本瓜成功的将打包大小从 3.1MB 变成了 2.36MB,文件数从 68个 打包到了 43个 !!!,既实现了拆包(拆公共库),也实现了并包(合并极小的包)。

    虽然这不会是最终的结果,但本瓜可以先下一个结论:

    webpack4 之 cacheGroups 分包【究极奥义】

    以下是 cacheGroups 配置:

     config.optimization.splitChunks({
            chunks: 'all',
             cacheGroups: {
                vue: {
                  name: 'chunk-vuejs',
                  test: /[\\/]node_modules[\\/]_?vue(.*)/,
                  priority: 20
                },
                elementUI: {
                  name: 'chunk-elementUI', // split elementUI into a single package
                  priority: 30, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
                },
                commons: { // split async commons chunk
                  name: 'chunk-async-commons',
                  minChunks: 2,
                  priority: 40,
                  chunks: 'async'
                },
                echarts: { // split echarts libs
                  name: 'chunk-echarts',
                  test: /[\\/]node_modules[\\/]_?echarts(.*)/,
                  priority: 50,
                  chunks: 'async'
                },
                zrender: { // split zrender libs
                  name: 'chunk-zrender',
                  test: /[\\/]node_modules[\\/]_?zrender(.*)/,
                  priority: 55,
                  chunks: 'async'
                },
                'manage-sendMsg': { // resolve src
                  name: 'chunk-manage-sendMsg',
                  test: resolve('src/views/manage/sendMsg'),
                  priority: 80,
                  chunks: 'async'
                },
                'manage-packageLink': { // resolve src
                  name: 'chunk-manage-packageLink',
                  test: resolve('src/views/manage/packageLink'),
                  priority: 80,
                  chunks: 'async'
                },
                ......
          })
    

    其实咱单独从配置上去做优化,可操作的空间并不大。我们还应该从打包分析结果去回看我们的代码细节,调整业务代码来优化打包结果,或许是最直接有效的优化思路之一。包括:如何整合或解耦业务?如何做组件化?组件怎么引?插件怎么引?引多少?......每个点都能再操作操作!

    • 尤其注意
    CommonJs(require)ES6(import)
    输出的是一个值的拷贝输出的是值的引用运行时加载编译时输出接口

    cacheGroups

    下面我们再具体看看 cacheGroups 最关键的配置:

    【重要】

    • name

    chunk 的文件名

    • test

    过滤 modules,默认为所有的 modules,可匹配模块路径或 chunk 名字,当匹配到某个 chunk 的名字时,这个 chunk 里面引入的所有 module 都会选中;

    • priority

    权重,数字越大表示优先级越高。一个 module 可能会满足多个 cacheGroups 的正则匹配,到底将哪个缓存组应用于这个 module,取决于优先级;

    • chunks(非常非常非常重要)

    有三个值:all、async、initial。

    这里是一段示例代码,来看看设置不同的 chunks,它们有什么样的打包区别:

    //app.js
    import "my-statis-module";
    
    if(some_condition_is_true){
      import ("my-dynamic-module")
    }
    console.log("My app is running")
    

    asyn : (default)

    会生成两个打包文件:

    1. bundle.js (包含 app.js + my-statis-module)
    2. chunk.js (只包含 my-dynamic-module)

    initial :

    会生成三个打包文件:

    1. app.js (只包含 app.js)
    2. bundle.js (只包含 my-static-module)
    3. chunk.js (只包含 my-dynamic-module)

    all :

    会生成两个打包文件:

    1. app.js (只包含 app.js)
    2. bundle.js (包含 my-static-module + my-dynamic-module)

    设置 "all" 大小将最小,区别使用这三者,是核心中的核心。


    【了解】
    • minSize

    表示被拆分出的 bundle 在拆分之前的体积的最小数值,只有 >= minSize 的 bundle 会被拆分出来;

    • maxSize

    表示被拆分出的 bundle 在拆分之前的体积的最大数值,默认值为 0,表示 bundle 在拆分前的体积没有上限;maxSize 如果为非 0 值时,不能小于 minSize;

    • minChunks

    表示在分割前,可被多少个chunk分享的最小值

    • reuseExistingChunk

    表示是否使用已有的 chunk,true 则表示如果当前的 chunk 包含的模块已经被抽取出去了,那么将不会重新生成新的,即几个 chunk 复用被拆分出去的一个 module;

    意外收获

    代码层面:这样写,user.png 会被单独打成一个包。打包出来 148B ,属实没必要!

    <img v-show="imageUrl" :src="imageUrl" class="sort-img">
    <img v-show="!imageUrl" src="~@/assets/user.png" class="sort-img">
    

    webpack4 之 cacheGroups 分包【究极奥义】 webpack4 之 cacheGroups 分包【究极奥义】

    如果改成这样,则不会再被单独打包了。

     <img :src="imageUrl?imageUrl:'~@/assets/user.png'" class="sort-img">
    

    回看其它代码,本瓜发现所有在条件判断里面引入的文件都会被单独打包。然而它们其中有些是可以调整写法的,真没必要将几 KB 的文件单独打包成一个几 B 的包文件。

    从打包的结果去检验代码,也是一种不错的优化手段!

    策略小结

    基于本次分包,本瓜简单梳理一下策略:

    1. 公共的库是一定要尽量拆的。
    2. 公共的库尽量做到按需加载,这也是优化首屏加载需要注意的。
    3. 分包不能太细,0KB 至 10 KB 的包是极小的包,应当考虑合并。10 KB 至 100 KB 的包是小包,比较合适;100 KB 至 200 KB 的包只能是比较核心重要的包,需要重点关注,大于 200KB 的包就需要考虑拆包了。当然,也不排除一些特殊情况。
    包大小策略
    0 KB 至 10 KB合并包10 KB 至 100 KB大小合适100 KB 至 200 KB核心包,重点关注大于 200 KB考虑拆包特殊情况特殊处理

    本次就先到这,打包无止境,愿这个世上没有打包攻城狮。

    关注公众号【掘金安东尼】,你的三连,我的动力!!!

    webpack4 之 cacheGroups 分包【究极奥义】


    起源地下载网 » webpack4 之 cacheGroups 分包【究极奥义】

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元