关于 webpack 的性能优化这块,前面已经写了两篇 2 章,一篇是介绍性能优化前的分析,另一篇是介绍速度提升和体积优化的主要方式,文章如下:
如何进行构建速度分析和体积分析?
如何提升构建速度,进行体积优化?
当然你如果对 webpack 原理,以及 loader 和 plugin 实现感兴趣也可以访问如下文章:
浅谈Webpack的本质
Loader处理非JavaScript模块详解
Plugin事件流机制详解
浅谈Webpack原理,以及loader和plugin实现
当然还有其他一些 webpack 的基础进阶用法文章,如下:
wepback进阶用法1:多入口构建/资源内联/脚本分离等
webpack进阶用法2:代码分割和动态引入的实现方式
webpack进阶用法3:如果将代码打包成一个通用JS库
接下去进入主题,了解 webpack 性能优化的其余几种方式:
1. 缓存:提升二次构建速度
babel-loader 开启缓存
babel-loader 的 cacheDirectory 属性默认值是 false。如果设置了这个参数,被转换的结果将会被缓存起来。当 webpack 再次编译时,将会首先尝试从缓存中读取转换结果,以此避免资源浪费。
module.exports = { module:{ rules:[ { test:/\.js$/, use:['babel-loader?cacheDirectory=true'], exclude:/node_modules/ } ] }}
复制代码
使用 cache-loader
cache-loader 仅限于在性能开销较大的 loader 之前添加它,以便将结果缓存到磁盘。这是因为保存和读取这些缓存文件存在时间开销。
module.exports = { module:{ rules:[ { test:/\.js$/ use:[ 'cache-loader', 'babel-loader' ], include:path.resolve('src') } ] }}
复制代码
使用 hard-source-webpack-plugin
这是 4.0 与 5.0 之间的一种过渡的使用缓存的方式。
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');module.exports = { plugins:[ new HardSourceWebpackPlugin() ]}
复制代码
terser-webpack-plugin 开启缓存
用于压缩 js 的插件,webpack5 已经集成最新版,当然如果还是用 4 版本的,可以留意下。
new TerserPlugin({ parallel:true, cache:true // 开启缓存})
复制代码
2. 减少文件搜索范围
优化 loader 配置
module.exports = { module:{ rules:[ { test:/\.js$/, use:['babel-loader?cacheDirectory=true'], // 只对src目录下的文件进行babel-loader转换 include: path.resolve(__dirname, 'src') } ] }}
复制代码
优化 resolve.modules 配置
resolve.modules 的默认值是 ['node_modules'],查找规则是从当前目录一级一级往上查找,直至找到想找的模块。但如果我们三方库都放在根目录的node_modules底下,则可如下配置,减少查找。
module.exports = { resolve:{ // 用于配置webpack从哪些目录下寻找第三方模块 modules:[ path.resolve(__dirname,'node_modules') ] }}
复制代码
优化 resolve.mainFields 配置
module.exports = { resolve:{ // package.json描述第三方模块的属性 // 用于配置第三方模块使用哪个字段入口文件 mainFields:['main'] }}
复制代码
优化 resolve.alias 配置
resolve.alias 配置项可以通过别名来把原导入路径映射成一个新的导入路径。
module.exports = { resolve: { // 通过 alias 把导入 vue 的语句换成直接使用单独完整的 vue.min.js 文件, // 减少耗时的递归解析操作 alias: { 'vue': path.resolve(__dirname, './node_modules/vue/dist/vue.min.js'), } },}
复制代码
优化 resolve.extensions 配置
resolve.extensions 用于配置在当导入语句没带文件后缀时,webpack 尝试询问文件是否存在使用的后缀列表。
module.exports = { resolve: { // 尽可能减少后缀尝试的可能性 extensions: ['js'], },}
复制代码
3. 图片压缩
采用 image-webpack-loader 进行图片压缩
rules: [{ test: /\.(gif|png|jpe?g|svg)$/i, use: [ 'file-loader', { loader: 'image-webpack-loader', options: { // 以下是针对每种图片类型优化器的配置 mozjpeg: { // 压缩jpeg progressive: true, }, // optipng.enabled: false will disable optipng optipng: { // 压缩png enabled: false, }, pngquant: { // 压缩png quality: [0.65, 0.90], speed: 4 }, gifsicle: { // 压缩gif interlaced: false, }, webp: { // 将JPG和PNG图像压缩为WEBP quality: 75 } } }, ],}]
复制代码
4. 删除无用 CSS
purgecss-webpack-plugin 和 mini-css-extract-plugin 配合使用
const path = require('path')const glob = require('glob')const MiniCssExtractPlugin = require('mini-css-extract-plugin')const PurgecssPlugin = require('purgecss-webpacak-plugin')
const PATHS = { src:path.join(__dirname,'src')}
module.exports = { module:{ rules:[ { test:/\.css$/, use:[ MiniCssExtractPlugin.loader, 'css-loader' ] } ] }, plugins:[ new MiniCssExtractPlugin({ filename:'[name].css', }), new PurgecssPlugin({ paths:glob.sync(`${PATHS.src}/**/*`,{nodir:true}) }) ]}
复制代码
5. 动态 Polyfill
我们希望浏览器能提供一些特性,但是它没有,我们写段代码来实现它,那这段代码可以成为补丁。
我们通常是通过 babel-polyfill.js 来解决这个,但是该库打包后体积比较大。因此我们可以通过动态 polyfill 来处理。
它的原理是:识别浏览器的 User Agent 下发不同的 Polyfill。
<script src="https://polyfill.io/v3/polyfill.min.js?features=Promise%2CArray.prototype.includes"></script>
复制代码
6. 总结
至此完成了 webpack 性能优化相关的学习。
''
评论 (2 条评论)