性能预算
对包体积、图体积和请求数设限,CI 中强制防回退。
为什么
性能预算是契约:"此页发不超 200KB JavaScript、500KB 图、不超 20 请求。"无它每 PR 加一点——这新依赖、那额外图——页面一年从 1s 到 4s 无单变更可怪。预算使每 KB 成刻意决定:PR 加 50KB 时开发者须要么证明合理、要么优化别的腾空间、要么减增加。这是防每个无预算团队终将遭受的慢静默性能死的唯一机制。预算设一次、CI 强制、定期审查——把性能 从反应救火变主动护栏。
何时使用
项目开始或性能成问题时设预算。每个 PR 强制。每季审查随团队改进收紧或预算阻合法功能时放宽。
如何做
1. 测当前性能设现实基线 - 关键页跑 Lighthouse、记当前包/图/请求计数 - 预算设当前 110%——紧到抓回退、松到不阻正常工作 - 团队优化时收紧预算向目标(如 200KB JS) 2. 用机器可读格式定义预算 - 包体积: package.json 中 size-limit 或 bundlesize - Lighthouse 分: lighthouserc.json 带断言 - 资源计数: 数 <script> 和 <img> 标签的自定义 CI 步 3. 每个 PR CI 中强制预算 - size-limit 和 lighthouse-ci 作 CI 步 - 任一预算超即构建失败 - PR 上评论显体积 delta(前 → 后) 4. PR 超预算时开发者须: - 优化: 别处减体积腾空间(摇树、代码分割、压缩) - 证明: 加评论解释为何增加必要且可接受 - 增预算: 审查后更新预算文件(最后手段,非常规) 5. 随时间追踪预算 - 仪表盘画实际包体积和 Lighthouse 分 - 标注部署——看哪些 PR 增包哪些减 - 团队缩预算时庆祝——使性能赢可见
示 例
// package.json——size-limit 预算
{
"size-limit": [
{ "path": "dist/main.js", "limit": "200 KB", "gzip": true },
{ "path": "dist/vendor.js", "limit": "150 KB", "gzip": true },
{ "path": "dist/styles.css", "limit": "30 KB", "gzip": true }
]
}
// lighthouserc.json——性能预算
{
"ci": {
"assert": {
"assertions": {
"largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
"cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
"total-blocking-time": ["warn", { "maxNumericValue": 300 }],
"resource-summary:script:size": ["error", { "maxNumericValue": 200000 }],
"resource-summary:image:size": ["error", { "maxNumericValue": 500000 }],
"resource-summary:script:count": ["warn", { "maxNumericValue": 15 }]
}
}
}
}
// CI: .github/workflows/budget.yml
name: Performance Budget
on: [pull_request]
jobs:
budget:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- name: 查包体积
run: npx size-limit
- name: 查 Lighthouse 预算
run: npx @lhci/cli autorun
- name: PR 评论体积 delta
uses: andresz1/size-limit-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
# 发: "包体积: 198 KB → 205 KB (+7 KB) ⚠️ 预算: 200 KB"常见问题
- ⚠设预算但 CI 不强制——预算记在 wiki 无人查,包随每 PR 过限增长因无自动门控。
- ⚠预算太紧(当前体积)阻每个加功能 PR,挫伤开发者致预算反复放松直到无意义。
- ⚠仅预算 JavaScript 忽图、字体和 CSS——JS 包 150KB(预算内)但页面发 3MB 未优化图,预算给虚假控制感。
- ⚠预算作警告非错误强制——CI 中警告被无视,构建过,回退到生产用户经历减速。
最佳实践
- ✓预算初设当前体积 110%,随时间收紧——这抓回退不阻正常工作,团队可随优化棘轮降。
- ✓所有资源类型(JS、CSS、图、字体)和所有性能指标(LCP、CLS、TBT)预算——只覆盖一维的预算给其他维虚假控制感 。
- ✓预算作 CI 错误非警告强制——警告被无视,错误强制开发者合并前处理回退,这是预算的全部意义。
- ✓PR 评论发体积 delta(前 → 后 → 预算)使开发者立见变更影响——PR 时可见防回退合并。