mcpField
P
performance-review

performance-review

github.com/shiplightai测试与质量2407 次安装16 周前更新
代码仓库

关于 performance-review

performance-review 是用于测量和评估 Web 应用性能的审查流程,面向发布前检查、性能回归排查和高流量准备。它通过浏览器测量 Core Web Vitals、页面加载、资源和运行时表现,并生成指标报告、修复建议及 YAML 回归测试。

主要功能

  1. 01Core Web Vitals 测量
  2. 02页面加载指标评估
  3. 03资源与 Bundle 检查
  4. 04运行时性能分析
  5. 05性能报告与 YAML 回归测试
  6. 06快速、默认和深入审查模式

适用场景

  1. 01发布前检查关键页面性能
  2. 02排查加载缓慢或交互迟滞
  3. 03评估新增依赖或第三方脚本影响
  4. 04为高流量活动准备性能基线

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/shiplightai/agent-skills --skill performance-review

安装后在 Claude Code 中输入/performance-review确认已加载。

详细介绍

性能评审

根据 Google 的核心网页指标阈值和行业基准,衡量并评估应用的性能。本次评审可发现开发期间难以察觉、但会影响真实用户的性能问题,例如包体积膨胀、布局偏移、交互缓慢、图片未优化以及阻塞渲染的资源。

适用场景

在以下情况下使用 /performance-review:

  • 发布前或添加重大功能后
  • 页面加载感觉缓慢,但不确定原因
  • 为高流量活动做准备
  • 添加新的依赖项或第三方脚本后
  • SEO 排名取决于性能分数
  • 用户反馈速度缓慢或放弃使用

参考标准

  • Google 核心网页指标 — LCP、INP、CLS(2024 年阈值)
  • Google Lighthouse — 性能评分方法
  • HTTP Archive — Web 性能基准(中位数、p75、p90)
  • Web.dev 性能指南 — 最佳实践
  • RAIL 模型 — 响应、动画、空闲、加载预算

阶段概览

Phase 1: EDUCATE   → Performance impact on business and what we measure
Phase 2: SCOPE     → Identify key pages, performance budget, baseline
Phase 3: ANALYZE   → Browser-based performance measurement
Phase 4: REPORT    → Findings with metrics, scores, and comparisons
Phase 5: REMEDIATE → Fix guidance + YAML regression tests

阶段 1:说明

为什么重要: 页面加载延迟 1 秒会使转化率降低 7%(Akamai)。自 2021 年起,Google 将核心网页指标用作排名信号。加载时间超过 3 秒的页面会流失 53% 的移动访客(Google)。Amazon 发现,延迟每增加 100ms,销售额就会损失 1%。性能是一项功能,而性能缺失则是一个缺陷。

本次评审会在浏览器中衡量真实性能,而不只是进行静态分析。我们会捕获实际加载时间、渲染行为和交互响应速度。


阶段 2:确定范围

收集背景信息
  1. 从代码库自动检测:

    • 构建系统(Webpack、Vite、Next.js 等)
    • 包分析配置(如有)
    • 图片优化流程(sharp、next/image 等)
    • 字体加载策略
    • 代码拆分配置
    • Service Worker / 缓存策略
    • CDN 配置
  2. 逐项询问用户:

    • 目标 URL:应用在哪里运行?(为获得更贴近实际的测量结果,优先使用生产环境)
    • 关键页面:哪些页面对性能最重要?(建议:落地页、主要功能页、数据密集型页面)
    • 性能预算:是否已有目标?(默认:核心网页指标的“良好”阈值)
    • 已知问题:是否有感觉缓慢的页面?(可选)
  3. 制定测量计划:

    • 测试页面(3-5 个关键页面)
    • 条件:模拟桌面端和移动端(Moto G4 / 慢速 4G)
    • 指标:核心网页指标及补充指标
    • 基线:首次运行建立基线以供对比

阶段 3:分析

使用 new_session 打开浏览器会话,并启用 record_evidence: true。针对范围内的每个页面,运行所有测量类别。

类别 A:核心网页指标(CWV)
检查 ID指标良好有待改进较差方法
CWV-01LCP(最大内容绘制)≤2.5s2.5-4.0s>4.0s使用 PerformanceObserver 监测 LCP 条目
CWV-02INP(交互到下一次绘制)≤200ms200-500ms>500ms点击关键交互元素,测量延迟
CWV-03CLS(累积布局偏移)≤0.10.1-0.25>0.25使用 PerformanceObserver 监测 layout-shift 条目

浏览器验证: 导航到每个页面,并通过 JavaScript 捕获指标:

// LCP
new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lcp = entries[entries.length - 1];
  console.log('LCP:', lcp.startTime);
}).observe({ type: 'largest-contentful-paint', buffered: true });

// CLS
let clsValue = 0;
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) clsValue += entry.value;
  }
  console.log('CLS:', clsValue);
}).observe({ type: 'layout-shift', buffered: true });
类别 B:页面加载性能(LOAD)
检查 ID检查项阈值方法
LOAD-01首字节时间(TTFB)≤800msperformance.timing.responseStart - navigationStart
LOAD-02首次内容绘制(FCP)≤1.8sperformance.getEntriesByName('first-contentful-paint')
LOAD-03DOM 内容加载完成≤2.0sperformance.timing.domContentLoadedEventEnd
LOAD-04页面总大小≤3MB(移动端)/ ≤5MB(桌面端)performance.getEntriesByType('resource') 求和
LOAD-05HTTP 请求数≤50统计资源条目数
LOAD-06可交互时间(TTI)≤3.8s长任务分析
LOAD-07总阻塞时间(TBT)≤200ms长任务总和(超过 50ms 的部分)
LOAD-08速度指数≤3.4s视觉进度分析

浏览器验证: 使用 Performance API 和 performance.getEntries() 收集所有指标。

类别 C:资源优化(RES)
检查 ID检查项标准方法
RES-01图像使用现代格式(WebP/AVIF)Web.dev检查图像 URL 和 Content-Type
RES-02图像尺寸适当(未过大)Web.dev比较显示尺寸与原始尺寸
RES-03图像启用延迟加载(首屏以下)Web.dev检查首屏以下图像是否设置 loading="lazy"
RES-04图像具有明确的尺寸(width/height)防止 CLS检查是否存在 width/height 属性
RES-05CSS 不阻塞渲染(或以内联方式提供关键 CSS)Web.dev检查 CSS 加载策略
RES-06JavaScript 使用 defer 或 async 加载Web.dev检查脚本加载属性
RES-07字体使用 font-display: swap 或 optionalWeb.dev检查 @font-face 声明
RES-08字体已预加载Web.dev检查是否存在 <link rel="preload" as="font">
RES-09启用 Gzip/Brotli 压缩HTTP 最佳实践检查 Content-Encoding 标头
RES-10使用 HTTP/2 或 HTTP/3HTTP 最佳实践通过 Performance API 检查协议
RES-11缓存标头有效HTTP 最佳实践检查静态资源的 Cache-Control
RES-12未加载未使用的 CSS/JS包效率通过 Page.startJSCoverage/startCSSCoverage 检查覆盖率

浏览器验证: 使用 JavaScript 检查所有已加载资源的类型、大小和加载属性。使用 performance.getEntriesByType('resource') 获取详细的资源指标。

类别 D:包分析(BUN)
检查 ID检查项阈值方法
BUN-01主 JS 包大小≤250KB(gzip 压缩后)检查主包的传输大小
BUN-02JS 总大小≤500KB(gzip 压缩后)汇总所有 JS 的传输大小
BUN-03CSS 总大小≤100KB(gzip 压缩后)汇总所有 CSS 的传输大小
BUN-04已实现代码拆分最佳实践检查是否存在多个 JS 分块
BUN-05无重复依赖项包效率分析分块内容中的重复项
BUN-06Tree shaking 有效包效率检查已知的大型未使用导出项
BUN-07生产环境未暴露源映射安全性/性能检查 .map 文件是否可访问
BUN-08第三方 JS 预算≤JS 总量的 30%计算第三方与第一方的比例

浏览器验证: 使用 Performance API 测量传输大小。检查源映射 URL。分析脚本的域名来源。

类别 E:运行时性能(RUN)
检查 ID检查项阈值方法
RUN-01交互期间没有长任务>50ms = 长任务使用 PerformanceObserver 监测长任务
RUN-02滚动性能流畅60fps滚动页面,测量帧丢失情况
RUN-03动画性能60fps触发动画,测量卡顿情况
RUN-04内存使用稳定(无泄漏)无增长趋势随时间测量 performance.memory
RUN-05DOM 节点数量不过多≤1500 个节点统计 document.querySelectorAll('*').length
RUN-06没有布局抖动0 次强制回流监测强制样式重新计算
RUN-07事件监听器效率高监听器不过多检查未进行节流的滚动/调整大小监听器

浏览器验证: 使用 JavaScript 测量性能指标,同时浏览并与应用交互。


第 4 阶段:报告

生成结构化报告,并保存到 shiplight/reports/performance-review-{date}.md:

# Performance Review Report
**Date:** {date}
**URL:** {url}
**Pages tested:** {list}
**Conditions:** Desktop + Mobile (simulated Moto G4 / Slow 4G)

## Overall Score: {X}/10 | Confidence: {X}%

## Core Web Vitals Summary
| Metric | Desktop | Mobile | Status |
|--------|---------|--------|--------|
| LCP | 1.8s | 3.2s | ⚠️ Mobile needs work |
| INP | 95ms | 180ms | ✅ Good |
| CLS | 0.05 | 0.15 | ⚠️ Mobile needs work |

## Score Breakdown
| Category | Score | Findings |
|----------|-------|----------|
| Core Web Vitals (CWV) | 6/10 | 1 high, 1 medium |
| Page Load (LOAD) | 7/10 | 1 high |
| Resources (RES) | 5/10 | 2 high, 2 medium |
| Bundle (BUN) | 6/10 | 1 high, 1 medium |
| Runtime (RUN) | 8/10 | 1 medium |

## Resource Waterfall
(Top 10 slowest resources with load times)

## Bundle Breakdown
| Category | Size (gzipped) | Budget | Status |
|----------|---------------|--------|--------|
| First-party JS | 180KB | 250KB | ✅ |
| Third-party JS | 220KB | 150KB | ❌ Over budget |
| CSS | 45KB | 100KB | ✅ |
| Images | 1.2MB | 1.5MB | ✅ |
| Fonts | 85KB | 100KB | ✅ |

## Findings
(structured findings with metrics and evidence)
置信度评分
  • 90-100%:在浏览器中测得具体数值(例如,LCP:3.2s)
  • 70-89%:根据资源分析得出(例如,检测到未优化的图片)
  • 50-69%:代码层面的模式(例如,未找到延迟加载属性)
  • 低于 50%:不要报告

第 5 阶段:修复

1. 修复指南(示例)
#### RES-01: Images not using modern formats
**Impact:** ~40% larger images than necessary, adds ~500KB to page weight
**Current:** 8 PNG images totaling 1.2MB
**Fix:** Convert to WebP with fallback:
- Use `<picture>` with WebP source and PNG fallback
- Or use Next.js `<Image>` / `sharp` for automatic format negotiation
- Expected savings: ~480KB (40% reduction)
**Priority files:**
- /images/hero.png (320KB → ~190KB as WebP)
- /images/features.png (280KB → ~165KB as WebP)
2. YAML 回归测试
- name: cwv-01-lcp-under-threshold
  description: Verify Largest Contentful Paint is under 2.5 seconds
  severity: high
  standard: Core-Web-Vitals-LCP
  steps:
    - description: Set up an LCP observer before navigation
      js: |
        // Set up LCP observer before navigation
        await page.evaluateOnNewDocument(() => {
          window.__lcp = 0;
          new PerformanceObserver((list) => {
            const entries = list.getEntries();
            window.__lcp = entries[entries.length - 1].startTime;
          }).observe({ type: 'largest-contentful-paint', buffered: true });
        });
    - URL: /
    - WAIT_UNTIL: Page has fully loaded including all images and content
      timeout_seconds: 30
    - description: Assert Largest Contentful Paint is under 2.5s
      js: |
        const lcp = await page.evaluate(() => window.__lcp);
        if (lcp > 2500) {
          throw new Error(`LCP is ${lcp}ms, exceeds 2500ms threshold`);
        }
        console.log(`LCP: ${lcp}ms (threshold: 2500ms)`);
    - VERIFY: Page loaded with Largest Contentful Paint under 2.5 seconds

将所有 YAML 测试保存到 shiplight/tests/performance-review.test.yaml。


深度级别

  • --quick:仅检查主页上的 Core Web Vitals。约 2 分钟。
  • 默认:检查关键页面上的所有类别,涵盖桌面端和移动端。约 8-12 分钟。
  • --thorough:检查所有类别 + 扩展页面 + 多次运行以提升统计置信度 + 运行时性能分析。约 20-30 分钟。

提示

  • 在生产环境(或类生产构建)中测量——开发模式下的性能会产生误导
  • 多次运行——性能测量结果会有差异;应关注趋势,而非单个数据点
  • 移动端模拟会暴露桌面端无法发现的问题——务必同时测试两者
  • 使用 performance.getEntries()——它是浏览器中最丰富的性能数据来源
  • 优先关注 Core Web Vitals——这是 Google 用于排名的指标
  • 使用 close_session 结束会话,并使用 generate_html_report 提供证据

评论

支持 Markdown