回答重点
在 Webpack 中实现持久化缓存有几个关键策略,最核心的就是利用文件内容哈希,使得文件名发生变化,这样浏览器就会识别为新的资源而不是使用缓存的旧资源。具体步骤如下:
1)使用 output.filename
和 output.chunkFilename
配置项来添加哈希:
javascript
output: {
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].js',
}
2)使用合适的插件来优化缓存,例如 HtmlWebpackPlugin
生成带有哈希的文件引用,以及 MiniCssExtractPlugin
用于 CSS 文件名哈希:
javascript
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
}),
]
3)开启长效缓存管理:使用 webpack.NamedModulesPlugin
和 webpack.HashedModuleIdsPlugin
,确保模块id在内容不变的情况下保持一致:
javascript
optimization: {
moduleIds: 'hashed',
}
plugins: [
new webpack.HashedModuleIdsPlugin(),
]
4)分离供应商代码(第三方库)和应用代码,利用 SplitChunksPlugin
:
javascript
optimization: {
splitChunks: {
chunks: 'all',
},
}
扩展知识
在实现持久化缓存方面,我们可以进一步优化和理解一些概念和工具:
1)Contenthash 与 Chunkhash :了解 contenthash
和 chunkhash
的区别至关重要。contenthash
是基于文件内容生成的哈希,任何内容改变都会导致哈希变化。而 chunkhash
则是基于整个 chunk 的内容进行哈希计算。
2)缓存优化策略:
- 浏览器缓存 :配置 HTTP 头,如
Cache-Control
和ETag
,使得浏览器缓存策略与文件名哈希结合,进一步提升缓存效率。 - Service Worker :利用 Service Worker 缓存策略,通过
Workbox
等工具实现更细粒度的缓存控制。
3)Tree Shaking 和 Dead Code Elimination:
- 使用
mode: 'production'
和TerserWebpackPlugin
来启用 Tree Shaking 和去除无用代码,减少最终产出文件体积。
4)Differential Loading :针对不同的浏览器特性生成不同的构建版本 (现代浏览器和旧版浏览器),利用 @babel/preset-env
的 targets
选项和 Webpack 的 environment
目标进行指导。
5)Monitor Cache Performance:使用工具如 Lighthouse 来分析和评估缓存性能,从具体的报告中找出改进点。