Skip to content
返回质量保障

性能预算

对包体积、图体积和请求数设限,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 时可见防回退合并。