浏览器缓存机制详解
浏览器缓存技术通过两种主要模式优化网络性能:强制缓存(强缓存)和协商缓存。这两种机制共同作用可显著减少网络请求量。
1. 缓存处理流程
当浏览器访问资源时,系统会执行如下流程:
- 检查本地缓存是否存在有效数据
- 若存在强缓存数据则直接使用
- 若强缓存失效则触发协商缓存验证
- 服务器根据验证结果返回304未修改或200新资源
- 最终完成页面渲染
2. 强制缓存实现
强制缓存无需与服务器通信,直接使用本地存储的资源。
2.1 HTTP头部配置
- Cache-Control:控制缓存策略
-max-age=3600设置有效期
-no-cache禁用强制缓存
-public/private控制缓存范围 - Expires:指定过期时间戳
2.2 服务端配置示例
// 使用Express框架配置
app.use('/static', express.static('public', {
maxAge: '1y',
etag: false,
lastModified: false
}));
2.3 缓存验证逻辑
function checkCacheValidity(cacheData) {
const now = Date.now();
if (cacheData.headers['cache-control']) {
const maxAge = parseMaxAge(cacheData.headers['cache-control']);
return now - cacheData.timestamp < maxAge * 1000;
}
return now < new Date(cacheData.headers.expires).getTime();
}
3. 协商缓存机制
当强制缓存失效后,浏览器通过验证请求判断资源是否更新。
3.1 验证头部参数
- Last-Modified / If-Modified-Since:时间戳验证
- ETag / If-None-Match:唯一标识验证
3.2 服务端实现示例
app.get('/api/data', (req, res) => {
const data = fetchData();
const etag = generateHash(data);
if (req.headers['if-none-match'] === etag) {
return res.status(304).end();
}
res.setHeader('ETag', etag);
res.setHeader('Last-Modified', new Date().toUTCString());
res.json(data);
});
3.3 验证流程实现
async function validateResource(url, cachedData) {
const headers = {
'If-None-Match': cachedData.etag,
'If-Modified-Since': cachedData.lastModified
};
try {
const response = await fetch(url, { headers });
if (response.status === 304) {
return { status: 'hit', data: cachedData };
} else {
const newData = await response.json();
return { status: 'update', data: newData };
}
} catch {
return { status: 'fallback', data: cachedData };
}
}
4. 实际应用配置
4.1 Nginx配置方案
server {
location ~ \.(js|css)$ {
expires 365d;
add_header Cache-Control "public, immutable";
etag on;
}
location ~ \.(html)$ {
expires 1h;
add_header Cache-Control "public, must-revalidate";
etag on;
}
}
4.2 Webpack构建优化
module.exports = {
output: {
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].chunk.js'
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
5. 缓存策略建议
| 资源类型 | 推荐策略 | 配置示例 |
|---|---|---|
| 静态资源 | 强缓存+版本号 | Cache-Control: public, max-age=31536000, immutable |
| HTML文件 | 协商缓存 | Cache-Control: no-cache |
| API响应 | 协商缓存 | Cache-Control: no-cache |
| 用户数据 | 禁用缓存 | Cache-Control: no-store |
6. 调试工具使用
function analyzeCachePerformance() {
performance.getEntriesByName('example.com').forEach(entry => {
console.log(`资源: ${entry.name}`);
console.log(`传输大小: ${entry.transferSize}B`);
console.log(`编码体积: ${entry.encodedBodySize}B`);
console.log(`解码体积: ${entry.decodedBodySize}B`);
if (entry.transferSize === 0 && entry.encodedBodySize > 0) {
console.log('状态: ✅ 强缓存命中');
} else if (entry.transferSize > 0 && entry.transferSize < entry.encodedBodySize) {
console.log('状态: 🔄 协商缓存命中');
} else {
console.log('状态: ⬇️ 新资源下载');
}
});
}