webpack 快速入门 系列 —— 性能 (4)

Tip:304 仍然会发送请求,通常请求头中 If-Modified-Since 的值和响应头中 Last-Modified 的值是相同的。

If-Modified-Since: Sat, 17 Jul 2021 02:34:06 GMT Last-Modified: Sat, 17 Jul 2021 02:34:06 GMT

接下来我给静态资源增加缓存,这里就增加一个 10 秒的缓存:

// server.js - app.use(express.static('dist')); + app.use(express.static('dist', { maxAge: 1000 * 10 }));

再次请求,发现 main.js 首先是 304,接下来10秒内状态码则是200,大小则指示来自内存,时间也变为 0 ms。过10秒后再次请求,又是 304。

现在有一个问题,在强缓存期间,如果出现了bug,我们哪怕修复了,用户使用却还是缓存中有问题的代码。

我们模拟一下这个过程图:先将缓存改长一点,比如 1 天,用户访问先输出 1,让浏览器缓存后,我们再修改代码让其输出 2,用户再次访问会输出什么?

// server.js app.use(express.static('dist', { maxAge: '1d' })); // index.js console.log('1');

重新打包生成 dist,接着用户通过浏览器访问,控制台输出 1。

修改 js,重新打包生成 dist,再次访问,控制台还是输入 1。

// index.js console.log('2');

注:不要强刷,因为用户不知道强刷,也不会去管。

于是我们打算从文件名入手来解决此问题,我们依次来看看 hash、chunkhash和conenthash。

hash

核心代码如下:

// index.js import './a.css' console.log('1'); // a.css p{color:red;} // webpack.config.js module.exports = { output: { filename: 'main.[hash:10].js', }, plugins: [ new MiniCssExtractPlugin({ filename: "[name].[hash:10].css", }) ] }

重新打包:

> npm run build > webpack-example3@1.0.0 build > webpack Hash: b2e057d598ca9092abd3 Version: webpack 4.46.0 Time: 4837ms Built at: 2021-07-14 8:17:54 ├F10: PM┤ Asset Size Chunks Chunk Names index.html 417 bytes [emitted] main.b2e057d598.css 12 bytes main [emitted] [immutable] main main.b2e057d598.js 5.22 KiB main [emitted] [immutable] main Entrypoint main = main.b2e057d598.css main.b2e057d598.js main.b2e057d598.js.map

主要看生成的 css 和 js 文件,名字中都带有相同的值 b2e057d598,取的是生成的 Hash 的前10位。index.html 中也会自动引入对应的文件名。

现在浏览器访问,文字是红色,控制台输出1。

接着模拟修复缺陷,将文字改为蓝色,再次打包。

p{color:blue;} > npm run build > webpack-example3@1.0.0 build > webpack Hash: ed2cd907a36536276d20 Version: webpack 4.46.0 Time: 4771ms Built at: 2021-07-14 8:29:14 ├F10: PM┤ Asset Size Chunks Chunk Names index.html 417 bytes [emitted] main.ed2cd907a3.css 13 bytes main [emitted] [immutable] main main.ed2cd907a3.js 5.22 KiB main [emitted] [immutable] main

浏览器访问,文字确实变为蓝色。但 js 和 css 都重新请求了,再看打包生成的文件,js 和 css 也都重新生成了新的文件名。这个会导致一个问题,只修改一个文件,其他的所有缓存都会失效。

Tip:这里修复的是 css,如果修复 js 也同样会导致所有缓存失效。

chunkhash

hash 会导致所有缓存失效,我们将其改为 chunkhash,还是存在相同的问题。请看示例:

将 hash 改为 chunkhash:

// webpack.config.js module.exports = { output: { filename: 'main.[chunkhash:10].js', }, plugins: [ new MiniCssExtractPlugin({ filename: "[name].[chunkhash:10].css", }) ] }

修改 css,然后重新打包,发现 js 和 css 文件也都重新生成了,虽然 chunkhash 与 hash 值不相同,但 main.js 和 main.css 中的 chunkhash 是一样的:

> npm run build > webpack-example3@1.0.0 build > webpack Hash: 8c1c035175aae3d36fea Version: webpack 4.46.0 Time: 5000ms Built at: 2021-07-14 9:16:46 ├F10: PM┤ Asset Size Chunks Chunk Names index.html 417 bytes [emitted] main.619734f520.css 13 bytes main [emitted] [immutable] main main.619734f520.js 5.22 KiB main [emitted] [immutable] main

Tip: 通过入口文件引入的模块都属于一个 chunk。这里 css 是通过入口文件(index.js)引入的,所以 main.js 和 main.css 的 chunkhash 值相同。

contenthash

contenthash 是根据文件内容来的,可以较好的解决以上问题。请看示例:

将 chunkhash 改为 contenthash,然后打包:

// webpack.config.js module.exports = { output: { filename: 'main.[contenthash:10].js', }, plugins: [ new MiniCssExtractPlugin({ filename: "[name].[contenthash:10].css", }) ] } > npm run build > webpack-example3@1.0.0 build > webpack Hash: 12994324788654e2ffc4 Version: webpack 4.46.0 Time: 5115ms Built at: 2021-07-14 9:26:59 ├F10: PM┤ Asset Size Chunks Chunk Names index.html 417 bytes [emitted] main.21668176f0.css 12 bytes main [emitted] [immutable] main main.8983191438.js 5.22 KiB main [emitted] [immutable] main

这次,js 和 css 的 hash 值不在相同。通过浏览器访问多次后,main.js 和 main.css 也都被强缓存。

修改css:

p{color:yellow;}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzzjsp.html