0%

webpack构建体积优化

本文介绍了几种 webpack 构建体积优化的方式。

图片压缩

Github - tcoopman/image-webpack-loader

在 webpack 中,图片压缩使用的是 image-webpack-loader 。这个 loader 是基于 node 库 imagemin 实现的。

imagemin 能够处理多种图片格式,能够使用第三方优化插件,如 pngquant、tinypng、pngcrush、optiopng 等。

压缩原理

pngquant:通过将 png 图像转换为具有 alpha 通道的8位 png 格式,显著减小文件大小。
tinypng:也是将 png 文件转化为8位 png 图片,同时剥离所有非必要的 metadata 信息。
pngcrush:通过尝试不同的压缩级别和 png 过滤方法来降低 png idat 数据流的大小。
optiopng:类似于 pngcrush,也是将 png 压缩为更小的尺寸。

使用

安装:

1
npm i image-webpack-plugin -D

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// webpack.config.js
rules: [{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
},
],
}]

具体参数说明参见 :Options 说明

Tree Shking

Tree Shaking 可以去除代码中无用的 js 代码,具体用法可参考之前的文章

去除无用 CSS

Tree Shaking 可删除的是无用的 js 代码,但是对于 CSS 代码却无能为力。
无用的 CSS 代码,可使用 PurifyCSS 或 uncss 删除。
PurifyCSS 通过遍历代码,识别已经用到的 CSS class,进而删除无用 CSS 代码。
uncss 使用 jsdom 加载 HTML,并使用 PostCSS 加载样式表,然后通过 document.querySelector 识别出在 HTML 中没出现的选择器。

由于 PurifyCSS 不再维护,所以在 webpack 中可以使用插件 purgecss-webpack-plugin 实现删除无用 CSS 代码的目的。
注意: purgecss-webpack-plugin 需要和 mini-css-extract-plugin 一同使用。

安装:

1
npm i purgecss-webpack-plugin -D

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// webpack.config.js
const path = require('path')
const glob = require('glob')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const PurgecssPlugin = require('purgecss-webpack-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 }),
})
]
}

动态 Polyfill

我们希望浏览器提供一些特性,但是没有,然后我们自己写一段代码来实现他,那这段代码就是 Polyfill。

在 React 中,官方推荐使用 babel-polyfill,但是这个库存在一个问题,就是会把所有的 polyfill 都打包进去,存在体积较大的问题。

Polyfill.io 提供了动态 polyfill 的功能,它会根据浏览器的UA不同,返回不一样的 polyfill,达到一个按需加载的作用。

使用方法也很简单,在 html 文件中引入即可:

1
<script src="https://polyfill.io/v3/polyfill.min.js"></script>

polyfill.io 可以附加查询参数来定制 polyfill,具体可参照官方文档。