写点什么

Webpack | 提升构建速度和体积优化的 N 种方式

用户头像
梁龙先森
关注
发布于: 2021 年 02 月 05 日
Webpack | 提升构建速度和体积优化的N种方式

关于 webpack 的性能优化这块,前面已经写了两篇 2 章,一篇是介绍性能优化前的分析,另一篇是介绍速度提升和体积优化的主要方式,文章如下:

如何进行构建速度分析和体积分析?

如何提升构建速度,进行体积优化?

当然你如果对 webpack 原理,以及 loader 和 plugin 实现感兴趣也可以访问如下文章:

浅谈Webpack的本质

Loader处理非JavaScript模块详解

Plugin事件流机制详解

浅谈Webpack原理,以及loader和plugin实现

当然还有其他一些 webpack 的基础进阶用法文章,如下:

wepback进阶用法1:多入口构建/资源内联/脚本分离等

webpack进阶用法2:代码分割和动态引入的实现方式

webpack进阶用法3:如果将代码打包成一个通用JS库


接下去进入主题,了解 webpack 性能优化的其余几种方式:

1. 缓存:提升二次构建速度
  1. babel-loader 开启缓存

babel-loader 的 cacheDirectory 属性默认值是 false。如果设置了这个参数,被转换的结果将会被缓存起来。当 webpack 再次编译时,将会首先尝试从缓存中读取转换结果,以此避免资源浪费。

module.exports = {	module:{  	rules:[      {      	test:/\.js$/,        use:['babel-loader?cacheDirectory=true'],        exclude:/node_modules/      }    ]  }}
复制代码
  1. 使用 cache-loader

cache-loader 仅限于在性能开销较大的 loader 之前添加它,以便将结果缓存到磁盘。这是因为保存和读取这些缓存文件存在时间开销。

module.exports = {	module:{  	rules:[      {      	test:/\.js$/        use:[        	'cache-loader',        	'babel-loader'        ],    		include:path.resolve('src')      }    ]  }}
复制代码
  1. 使用 hard-source-webpack-plugin

这是 4.0 与 5.0 之间的一种过渡的使用缓存的方式。

const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');module.exports = {	plugins:[  	 new HardSourceWebpackPlugin()  ]}
复制代码
  1. terser-webpack-plugin 开启缓存

用于压缩 js 的插件,webpack5 已经集成最新版,当然如果还是用 4 版本的,可以留意下。

new TerserPlugin({	parallel:true,  cache:true // 开启缓存})
复制代码
2. 减少文件搜索范围
  1. 优化 loader 配置

module.exports = {	module:{  	rules:[      {      	test:/\.js$/,        use:['babel-loader?cacheDirectory=true'],        // 只对src目录下的文件进行babel-loader转换        include: path.resolve(__dirname, 'src')      }    ]  }}
复制代码
  1. 优化 resolve.modules 配置

resolve.modules 的默认值是 ['node_modules'],查找规则是从当前目录一级一级往上查找,直至找到想找的模块。但如果我们三方库都放在根目录的node_modules底下,则可如下配置,减少查找。

module.exports = {	resolve:{    // 用于配置webpack从哪些目录下寻找第三方模块  	modules:[    	path.resolve(__dirname,'node_modules')    ]  }}
复制代码
  1. 优化 resolve.mainFields 配置

module.exports = {	resolve:{     // package.json描述第三方模块的属性    // 用于配置第三方模块使用哪个字段入口文件  	mainFields:['main']  }}
复制代码
  1. 优化 resolve.alias 配置

resolve.alias 配置项可以通过别名来把原导入路径映射成一个新的导入路径。

module.exports = {  resolve: {    // 通过 alias 把导入 vue 的语句换成直接使用单独完整的 vue.min.js 文件,    // 减少耗时的递归解析操作    alias: {      'vue': path.resolve(__dirname, './node_modules/vue/dist/vue.min.js'),    }  },}
复制代码
  1. 优化 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 性能优化相关的学习。


''


发布于: 2021 年 02 月 05 日阅读数: 44
用户头像

梁龙先森

关注

脚踏V8引擎的无情写作机器 2018.03.17 加入

还未添加个人简介

评论 (2 条评论)

发布
用户头像
动态 polyfill 会不会受国内网络影响加载很慢?
2021 年 02 月 06 日 08:16
回复
库通常引用cdn的资源,好比阿里的。那cdn作为内容分发平台,可以让用户就近获取所需内容,有效降低网络拥塞,不会慢。
2021 年 02 月 06 日 11:21
回复
没有更多了
Webpack | 提升构建速度和体积优化的N种方式