场景:每次代码合并到主分支后自动部署
# 部署脚本自动读取 Manifest 刷新 CDN
FILES=$(jq -r '.[]' manifest.json | tr '\n' ' ')
curl -X POST "https://cdn.com/purge" -d "files=$FILES"
效果:部署耗时从 20 分钟(手动)→ 2 分钟(自动化)场景:紧急修复线上 Bug 后,部分用户仍访问旧版本
// 根据用户上报的版本号定向清理缓存
const badVersion = 'v1.2.3';
const filesToPurge = Object.values(manifest[badVersion]);
purgeCDN(filesToPurge);
效果:精准清理问题版本文件,避免影响其他用户场景:优化首屏加载速度
# 根据 Manifest 中的哈希文件设置长效缓存
location ~* \.[a-f0-9]{8}\.(js|css)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
效果:缓存命中率从 60% → 98%,加载速度提升 3 倍问题:项目庞大,静态资源引用分散,新人难以理清依赖
Manifest 方案:
// 基于 manifest.json 生成可视化图表
{
"src/main.js": ["vendor.js", "utils.js"],
"src/home.js": ["header.js", "footer.js"]
}
效果:新人理解资源结构的时间从 1 天 → 1 小时场景:同时存在测试、预发、生产多个环境
// 根据环境变量加载对应 Manifest
const env = process.env.NODE_ENV;
const manifest = require(`./manifest-${env}.json`);
// 动态生成资源标签
manifest.entryPoints.forEach(file => {
document.write(``);
});
效果:环境切换错误率从 30% → 0%集成方案:
// 上报资源加载耗时
const entries = window.performance.getEntriesByType('resource');
const stats = entries.map(entry => ({
name: entry.name,
duration: entry.duration,
version: manifest[entry.name] // 通过 Manifest 关联版本
}));
sendAnalytics(stats);
紧急场景 | Manifest 的救援方案 |
---|---|
用户投诉页面空白 | 根据 Manifest 确认是否资源加载失败 |
老板要看版本更新记录 | 提取 Manifest 中的版本时间线 |
安全团队审计代码 | 通过 Manifest 追溯第三方库版本 |
Manifest 如同城市的地下水管——平时看不见,但停水时才知道它多重要。
它默默记录着每次构建的「资源基因」,在部署、排障、优化时提供精准坐标,是现代化前端工程真正的「无名英雄」。
这段 Nginx 配置用于 设置长效缓存规则,专门针对文件名中包含 8位哈希值 的 JS/CSS 文件。
location ~* \.[a-f0-9]{8}\.(js|css)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
代码部分 | 含义 | 作用原理 |
---|---|---|
`location ~* .[a-f0-9]{8}.(js | css)$` | 匹配所有以 .js 或 .css 结尾,且文件名中包含 8位十六进制字符的文件 |
expires 1y; |
设置浏览器缓存过期时间为1年 | 浏览器在1年内重复访问时,直接使用本地缓存,无需请求服务器 |
add_header Cache-Control "public, immutable"; |
添加 HTTP 响应头,声明资源可被公共缓存且内容不可变 | public : 允许 CDN 等中间代理缓存immutable : 明确告知浏览器内容永不变化,跳过缓存校验逻辑 |
哈希文件名的唯一性
当文件内容变化时,构建工具会生成新的哈希值,如:
main.3a5b7d9e.js
main.7f8e2d1a.js
缓存策略的优势
适用场景
这段 JavaScript 代码用于 采集页面资源加载性能数据,并与 Manifest 中的版本信息关联上报。
const entries = window.performance.getEntriesByType('resource');
const stats = entries.map(entry => ({
name: entry.name,
duration: entry.duration,
version: manifest[entry.name]
}));
sendAnalytics(stats);
代码部分 | 含义 | 作用原理 |
---|---|---|
window.performance.getEntriesByType('resource') |
获取所有资源的加载性能数据 | 返回一个数组,包含图片、JS、CSS 等所有资源的加载耗时、大小等信息(如图) |
entries.map(...) |
将原始数据转换为包含版本信息的结构 | 遍历每个资源,提取名称、加载耗时,并通过 Manifest 映射到版本号 |
sendAnalytics(stats); |
将处理后的数据发送到分析平台 | 通常结合监控系统(如 ELK、自研平台)展示趋势,或触发告警 |
资源加载性能透明化
通过 window.performance
API 可获取到:
duration
: 资源从开始加载到完成的总时间transferSize
: 传输大小(含头部)initiatorType
: 发起者类型(如 script
、img
)版本关联精准定位问题
main.3a5b7d9e.js
平均加载耗时从 200ms 增至 1500ms数据驱动优化决策
指标 | 优化前 | 优化后 | 分析方法 |
---|---|---|---|
首屏JS加载耗时 | 1200ms | 400ms | 对比版本变更前后的耗时数据 |
图片传输大小 | 1.2MB | 300KB | 筛选同一版本下资源类型数据 |
正则表达式误匹配
vendor.1234567z.js
(含字母 z
)也会被匹配[a-f0-9]
缓存失效场景
数据采样率
if (Math.random() < 0.01) sendAnalytics(stats);
版本信息维护
v1.2.3
)用户体验
开发效率
最终效果:
用户访问更快,开发者排查问题更准,业务稳定性更高!