0%

webpack构建体积优化

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

图片压缩

Github - tcoopman/image-webpack-loader

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

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

压缩原理

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 代码,可使用 PurifyCSSuncss 删除。
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,具体可参照官方文档