长缓存优化方案
长缓存优化方案
长缓存优化是Webpack构建中提升应用加载性能的关键手段。通过合理配置文件名哈希、代码拆分和模块标识,可以确保用户浏览器缓存尽可能多的静态资源,减少重复下载。
哈希策略选择
Webpack提供三种哈希生成方式:
[hash]
:整个项目构建的哈希值[chunkhash]
:根据入口文件生成的哈希[contenthash]
:根据文件内容生成的哈希
推荐使用[contenthash]
,它只在文件内容变化时才会改变:
output: {
filename: '[name].[contenthash:8].js',
chunkFilename: '[name].[contenthash:8].chunk.js'
}
模块标识固化
Webpack默认使用数字ID作为模块标识,这会导致无关修改影响所有chunk的hash。解决方案是使用HashedModuleIdsPlugin
:
plugins: [
new webpack.HashedModuleIdsPlugin({
hashFunction: 'sha256',
hashDigest: 'hex',
hashDigestLength: 8
})
]
运行时代码分离
将运行时代码提取到单独文件,避免业务代码修改影响运行时缓存:
optimization: {
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
}
}
第三方库缓存策略
对稳定不变的第三方库使用单独chunk:
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
动态导入优化
使用魔法注释为动态导入的模块命名,保持缓存稳定性:
import(/* webpackChunkName: "lodash" */ 'lodash').then(({ default: _ }) => {
// 使用lodash
})
清单文件处理
确保正确生成和引用manifest文件:
new WebpackManifestPlugin({
fileName: 'asset-manifest.json',
publicPath: '/',
generate: (seed, files) => ({
files: files.reduce((manifest, file) => {
manifest[file.name] = file.path
return manifest
}, seed)
})
})
内容安全策略集成
配置合适的Cache-Control头和服务端缓存策略:
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
版本文件自动管理
创建版本标记文件帮助客户端检测更新:
const { GitRevisionPlugin } = require('git-revision-webpack-plugin')
plugins: [
new GitRevisionPlugin({
versionCommand: 'describe --always --tags --dirty'
}),
new webpack.DefinePlugin({
'process.env.BUILD_VERSION': JSON.stringify(
new GitRevisionPlugin().version()
)
})
]
预加载关键资源
使用preload
和prefetch
优化资源加载:
import(/* webpackPrefetch: true */ './path/to/Component')
模块依赖分析
利用webpack-bundle-analyzer
识别优化机会:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: 'bundle-report.html',
openAnalyzer: false
})
]
持久化缓存配置
启用文件系统缓存提升构建性能:
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename]
}
}
哈希长度优化
平衡哈希长度与碰撞概率:
output: {
filename: '[name].[contenthash:8].js',
chunkFilename: '[name].[contenthash:8].chunk.js',
assetModuleFilename: '[name].[hash:8][ext][query]'
}
服务端渲染兼容
处理SSR环境下的资源引用:
const assets = require('./asset-manifest.json')
function renderHtml() {
return `
<!DOCTYPE html>
<html>
<head>
<link href="${assets['main.css']}" rel="stylesheet">
</head>
<body>
<script src="${assets['main.js']}"></script>
</body>
</html>
`
}
资源预加载策略
基于使用分析配置资源预加载:
plugins: [
new PreloadWebpackPlugin({
rel: 'preload',
include: 'initial',
fileBlacklist: [/\.map$/, /hot-update\.js$/]
})
]
多环境配置处理
区分开发和生产环境的缓存策略:
const isProduction = process.env.NODE_ENV === 'production'
output: {
filename: isProduction
? '[name].[contenthash:8].js'
: '[name].js'
}
资源指纹校验
确保资源完整性:
<script
src="app.8a7b3c.js"
integrity="sha384-5N5S5Q5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5"
crossorigin="anonymous">
</script>
构建信息注入
将构建信息嵌入应用便于调试:
const { DefinePlugin } = require('webpack')
const buildDate = new Date().toISOString()
plugins: [
new DefinePlugin({
__BUILD_DATE__: JSON.stringify(buildDate),
__GIT_HASH__: JSON.stringify(require('child_process')
.execSync('git rev-parse HEAD')
.toString().trim())
})
]
资源加载监控
实现资源加载性能监控:
window.addEventListener('load', () => {
const entries = performance.getEntriesByType('resource')
const jsResources = entries.filter(
e => e.initiatorType === 'script'
)
// 上报资源加载耗时
})
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:按需加载与路由懒加载
下一篇:服务端渲染优化要点