携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
webpack介绍
-
webpack大家都知道,是目前主流的前端模块打包工具,也是现代js应用的静态模块打包工具,webpack会从一个或多个入口点构建一个依赖图,然后组成一个或者多个bundles,为静态资源,用于展示内容。
-
webpack性能优化分两个部分,一是提升webpack打包速度,一是优化前端性能,本文着重介绍打包速度优化,整理了比较全面的内容。
打包速度优化
node
npm/yarn
webpack
版本升级,较高的版本打包速度也会很快- 优化loader配置
- 降低打包频率(几个方向)
exclude: /node_modules/
include: path.resolve(__dirname, '../src')
只对src下的进行打包- 通过正则优化,提高性能
- babel-loader支持缓存,通过
cacheDirectory
选项开启
- 降低打包频率(几个方向)
- 减少查找过程
resolve: {extension: ['js', 'jsx']}
引入时可不输入后缀mainFiles: ['index']
只采用index作为入口文件的描述字段,以减少搜索步骤- modules指定范围优先查找
modules:[path.resolve(__dirname, 'node_modules'), 'node_modules']
- alias减少查找过程
alias: {alias: path.resolve(__dirname, '../src/alias')}
- 利用多线程提高构建速度,如
thread-loader
(parallel-webpack
happypack
)等插件 - 充分利用缓存提升二次构建速度
- babel-loader 开启缓存
- 使用 cache-loader 或者 hard-source-webpack-plugin
- terser-webpack-plugin 开启缓存
- 提取公共代码
- 使用splitChunks进行分包
- 基础包分离
- 使用
html-webpack-externals-plugin
,将基础包通过 CDN 引入,不打入 bundle 中 - 使用
SplitChunksPlugin
进行(公共脚本、基础包、页面公共文件)分离(Webpack4内置) ,替代了 CommonsChunkPlugin 插件
- 使用
- 按需加载
- es的import语法 (可以结合webpack魔法函数,按模块加载)
require.ensure
方式
- 缩小打包作用域(也算是减少查找过程的一种)
- noParse 对完全不需要解析的库进行忽略 (不去解析但仍会打包到 bundle 中,注意被忽略掉的文件里不应该包含 import、require、define 等模块化语句)
- IgnorePlugin (完全排除模块)
- 通过externals配置来提取常用库(资源cdn)
- Tree shaking
- tree shaking就是在打包过程中,找到项目中没有用到的死代码进行删除,原理是检测工程中没有引用过的模块并进行标记,在资源压缩时将它们从最终的bundle中去掉(只能对ES6 Modlue生效) 开发中尽可能使用ES6 Module的模块,提高效率
- 禁用 babel-loader 的模块依赖解析,否则 Webpack 接收到的就都是转换过的 CommonJS 形式的模块,无法进行 tree-shaking
- 代码与图片压缩
webpack-paralle-uglify-plugin
可以多进程并行压缩- 通过
mini-css-extract-plugin
提取 Chunk 中的 CSS 代码到单独文件,通过 css-loader 的 minimize 选项开启 cssnano 压缩 CSS。 image-webpack-loader
进行图片压缩
- 合理使用
sourceMap
,选择最适合项目的方式
瓶颈分析
- 在其他方面我们还可以通过可视化分析,分析打包瓶颈,如
- 测量构建时间
speed-measure-webpack-plugin
- 分析包内容
webpack-bundle-analyzer
- 生成统计文件
stats.json
- 官方可视化分析工具
Webapck Analyse
webpack-chart
:webpack stats
可交互饼图。
- 测量构建时间
结语
- 另外推荐个VSCode插件
Import Cost
,安装后可以看到每个页面引入包的大小,帮助我们进行实时分析。 - 打包速度优化没有银弹,需要从多个方面考虑,最适合自己项目的方案,适当做一些取舍。