profile 概览
¶本文总结了一些首屏加载优化的webpack实践, 分为如下几个模块
- bundle analysis 打包分析
- code coverage 代码覆盖率
- magic comments 魔法注释
- prefeching/preloading 预加载
- code splitting 代码分割
- lazy loading 懒加载(按需加载)
- babel, babel-polyfill与babel-runtime
- tree shaking 摇树
- sourcemap 源码映射配置
¶本文所用demo代码的仓库地址
https://github.com/atbulbs/webpack_optimization
bundle analysis 打包分析
官方推荐的一些打包分析插件 https://webpack.js.org/guides/code-splitting/#bundle-analysis
安装和使用webpack-bundle-analyzer https://github.com/webpack-contrib/webpack-bundle-analyzer
1 | # 生成stats.json文件 |
code coverage 代码覆盖率
官方文档: https://developers.google.com/web/updates/2017/04/devtools-release-notes
参考文档: https://blog.logrocket.com/using-the-chrome-devtools-new-code-coverage-feature-ca96c3dddcaf/
- 适用于JS和CSS
- 若某文件代码覆盖率低, 影响首屏时间和性能
- 解决: 首屏用户交互后才执行的关键代码预加载 + 非关键代码懒加载 + 移除无用代码 tree shaking
1 | // 查看代码覆盖率 |
magic comments 魔法注释
官方文档: https://webpack.js.org/api/module-methods/#magic-comments
1 |
|
prefeching/preloading 预加载
官方文档: https://webpack.js.org/guides/code-splitting#prefetchingpreloading-modules
实现第一次加载的时候就是最快的, webpack推荐交互的代码放到异步加载的模块里去写
prefeching/preloading可实现网页空闲时预先加载异步模块
1 | // src/click.js |
code splitting 代码分割
官方文档 https://webpack.js.org/guides/code-splitting
-
分割业务代码和库代码, 不然打包文件会很大, 首次访问加载时间会很长
-
而且如果不分割, 修改业务代码后, 重新访问, 又全部得重新加载库代码
-
分割方式: 配置 + 同步引入 与 动态引入(无需做任何配置)
动态引入文档 https://webpack.js.org/guides/code-splitting#dynamic-imports
1 | function getComponent () { |
SplitChunksPlugin官方文档: https://webpack.js.org/plugins/split-chunks-plugin/
1 | // splitPlugin 配置 |
lazy loading 懒加载(按需加载)
官方文档: https://webpack.js.org/guides/lazy-loading
前端框架结合webpack实现懒加载: https://webpack.js.org/guides/lazy-loading#frameworks
1 | // 点击页面才会加载lodash代码 |
babel, babel-polyfill与babel-runtime
¶对比:
- babel只转换语法, 不转换兼容api, 很多模块中很可能有重复helper函数
- babel-polyfill在全局做兼容, 会污染全局变量, 不建议在类库中使用
- babel-runtime属于babel的包, 也可提供polyfill, 且是默认按需加载的, helper函数会作为公共的模块使用, 缺点: 业务代码中的实例方法会失效
- 使用了babel-plugin-transform-runtime, babel就会启用bable-runtime
¶总结:
- 业务代码使用 babel-polyfill + 按需引入
- 类库代码使用 babel-runtime
¶最佳实践
- 业务代码可使用 useBuiltIns 配置, 会自动按需引入babel-polyfill, 无需手动引入babel-polyfill
tree shaking 根据引入的按需打包, 摇晃掉模块里与树没有关联的无用的模块
官方文档: https://webpack.js.org/guides/tree-shaking
官方文档: https://webpack.js.org/configuration/optimization#optimizationusedexports
关于静态模块结构的官方文档: https://exploringjs.com/es6/ch_modules.html#static-module-structure
1 | // Tree Shaking只支持 ES Module(静态引入), 不支持Common JS(动态引入) |
sourcemap 源码映射
官方文档: https://webpack.js.org/configuration/devtool#devtool
1 | devtool: 'none' // 关闭sourcemap |