优化代码运行性能

Code Split

把代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。代码分离可以用于获取更小的 bundle,以及控制资源加载优先级,如果使用合理,会极大影响加载时间。

常用的代码分离方法有三种:

  • 入口起点: 在 entry 中手动分离(见 output.md)

  • 防止重复:使用 Entry dependenciesSplitChunksPppplugin 去重分离

  • 动态导入:通过模块的内联函数来分离代码

入口起点

output.md,这种方法存在一些隐患:

  • 如果 entry 中多个 chunk 包含同一个模块,那这个模块会被重复引入

  • 不够灵活,不能动态地将核心应用逻辑中的代码拆分出来

防止重复

入口依赖

略,详见:代码分离 | webpack 中文文档 (docschina.org)

SplitChunksPlugin

将公共的依赖模块提取出来

webpack.config.js

假设 index.js 和 print.js 都引入了 lodash,打包后,第三方库 lodash 已经被单独提取出来

对比不提取时候的体积

动态导入

使用 import()

webpack.config.js

index.js

预获取/预加载模块

略,详见:代码分离 | webpack 中文文档 (docschina.org)

Cache

若打包的 bundle 文件名不改变,浏览器就会命中缓存

修改输出的文件名

使用文件内容的 hash 值来命名 bundle,使得在 bundle 不变时,hash 值也不改变

webpack.config.js

输出的文件:

💡 然而这样的方法并不能完全确保在文件内容不改变时保持 hash 值不变,因为入口 chunk 中可能包含了某些引导模板

提取引导模板 (extracting boilerplate)

使用 SplitChunksPlugin 可以将模块分离到单独的 bundle 中。利用 optimization.runtimeChunk 将 runtime 代码拆分为一个单独的 chunk

webpack.config.js

构建后,runtime 代码已经被提取出来

接着,我们还可以将第三方库(如 react、lodash)的代码提取到单独的 vendor chunk 中

webpack.config.js

再次构建,不仅 runtime 代码被提取出来,第三方库也被提取了出来

模块标识符*

vendor bundle 会随着自身的 module.id 的变化,而发生变化,但这不符合需求

Tree Shaking

Tree Shaking 是一种通过消除最终文件中未使用的代码来优化体积的方法。

你可以将应用程序想象成一棵树。绿色表示实际用到的 source code(源码) 和 library(库),是树上活的树叶。灰色表示未引用代码,是秋天树上枯萎的树叶。为了除去死去的树叶,你必须摇动这棵树,使它们落下。

webpack.config.js

math.js

bundle.js

side-effect-free

side-effect-free没有副作用,是指 tree shaking 不会错误地把代码给剔除掉。但是真实中的项目不是所有的代码都是这么的纯粹,是 side-effect-free 的。

因此,要在 package.json 中,指定那些不纯粹即不是side-effect-free的文件

当然,如果所有的文件都是 side-effect-free,那么在 package.json 中直接指定

最后,要将 mode 切换为 production,才会真正的将不需要的代码给剔除

总结

  • 必须依赖 ES6 的 import export 特性

  • 确保编译器没有将 ES6 转换为 CommonJS

  • 要添加 sideEffects 属性

  • 使用 production mode

lazy load

Last updated