当前市面上大部分前端应用都是基于 webpack 进行构建,而随着应用日益庞大,webpack 应用就会出现构建速度慢,构建结果体积大等一系列问题。
一、webpack 应用治理应该从哪个方向入手?
随着应用的不断迭代,webpack 应用最常见的两个问题就是:
构建速度慢;
构建体积大。
有一个很简单的划分方式,就是以构建(build)为分界线,分成前向治理和后向治理:
前向治理:提升构建速度;
后向治理:保证构建结果质量。
我们的治理方向,就是围绕前向治理和后向治理。
二、前向治理包含哪些内容?
前向治理的核心概念,就是一个字 `快`,目的就是提升构建速度,市面上大部分 webpack 优化文章都是这一类提升构建速度的文章,所以这里就简单介绍一些不错的实践
1. 利用 SMP 采集 webpack 数据指标
数据先行,通过 speed-measure-webpack-plugin 采集性能指标,可以得到 webpack 在整个编译过程中在 loader、plugin 上花费的时间,基于该数据可以专项的进行优化和治理。
2. 开启缓存
如果通过 SMP 分析得知在 loader 编译过程耗时较多,那么可以在核心 loader,例如 babel-loader 中添加缓存。
3. 开启 happyPack 多线程编译
如果通过 SMP 分析得知在 loader 编译过程耗时较多,还可以通过使用 happyPack,开启多线程编译,提升开发效率。
4. 使用 dll 技术
dll 可以简单理解成提前打包,例如 lodash、echarts 等大型 npm 包,可以通过 dll 将其提前打包好,这样在业务开发过程中就不用再重复去打包了,可以大幅缩减打包时间。
5. 升级到 webpack5
webpack5 利用 `持久缓存` 来提高构建性能,或许升级 webpack 后,前述的各种优化,都将成为历史。
三、后向治理包含哪些内容?
后向治理主要保证构建结果的质量
1. 可视化分析构建结果
很常见的就是 webpack-bundle-analyzeer,提供打包结果的可视化展示,如上图给予的决策帮助是:
是否需要按需加载;
是否需要提取公共代码;
是否需要制定 cacheGroup 的策略。
2. 清理 deadcode
业务开发过程中,随着业务迭代,经常有些文件、模块及代码被废弃,这些废弃代码随着时间推移,将逐渐变为历史包袱,所以针对构建后结果,我们要做的就是清理其中的 deadcode。
前面 webpack-bundle-analyzeer 虽然是最常用的插件,但依旧有一些缺陷:
1)体积超小的 deadcode 模块引用,无法被准确识别。
例如上图:
lodash 体积大一下子就能被发现,就会意识到重复引用或者是未使用
但 deadcode 模块 c 体积很小,即便被 chunk1、chunk2 都引用了,也不一定能立刻发现,很容易被带到线上
而且这种 deadcode 也无法通过 splitchunk 来进行优化,因为 splitchunk 根据引用次数提取公共代码,无法分辨是否是废弃代码,所以对模块 c.js 这种的 deadcode 就无力了
2)tree-sharking 只保留有用的代码,但 deadcode 还在那里。
tree-sharking 大家都了解,摇掉不需要的代码,做为最终的输出结果,但反过来说,这些废弃代码依旧在本地真实不虚的存在着。
所以如何能准确的清理掉 deadcode 呢?这就需要通过 webpack 的 统计信息(stats)
来进行更细节的分析
3. 统计信息(stats)
stats 是通过 webpack 编译源文件时,生成的包含有关于模块的统计数据的 JSON 文件,这些统计数据不仅可以帮助开发者来分析应用的依赖图表,还可以优化编译的速度。
通过上述全局命令即可输出统计信息,例如:
其中:modules:表示 module 的集合
module:webpack 依赖树中的真实模块;
chunks:表示 chunk 的集合;
chunk:包含 entry 入口、异步加载模块、代码分割(code spliting)后的代码块。
通过对 modules 和 chunks 加以分析,就可以得到 webpack 完整的依赖关系,从而梳理出废弃文件及废弃代码,同时也可以根据业务形态进行定制。
4. webpack-deadcode-plugin
前面提到分析 stats.json,但因为是原始数据,数据量比较大,有一定处理和清洗成本,所以可以使用开源的 webpack-deadcode-plugin 这个插件
通过 webpack-deadcode-plugin,可以快速筛选出:
1)未使用的文件;
2)未使用的已暴露变量。
5. 结合 eslint、tslint 进行治理
lint 可以快速的扫描出未使用的变量,这能够极大的提升我们的 deadcode 清理效率。
1)首先通过 lint 对未使用变量进行清理;
2)再通过 webpack-deadcode-plugin 再扫描出未使用文件和未使用的导出变量。
顿时整个应用干干净净,舒舒服服!
四、参考
speed-measure-webpack-plugin:
https://github.com/stephencookdev/speed-measure-webpack-plugin
happyPack:
https://github.com/amireh/happypack
webpack-bundle-analyzeer:
https://github.com/webpack-contrib/webpack-bundle-analyzer
stats:
https://webpack.js.org/api/stats/
webpack-deadcode-plugin:
https://github.com/MQuy/webpack-deadcode-plugin
作者介绍:
阿里影业高级开发工程师 百命
相关阅读
评论