performance-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
<objective> Measure, assert, and protect application performance with budgets enforced in CI, not subjective "feels fast enough" assessments. This skill covers two domains: **load testing** (can the backend handle traffic?) and **web performance** (is the frontend fast for users?). A report that says "LCP is 3.2s" is information; a CI gate that fails the build at 2.5s is accountability. </objective>
<objective> 通过在CI中强制执行预算来衡量、验证并保障应用性能,而非依赖主观的“感觉足够快”评估。本技能涵盖两大领域:**负载测试**(后端能否承受流量?)和**Web性能**(前端对用户而言是否快速?)。一份显示“LCP为3.2秒”的报告只是信息;而当LCP超过2.5秒时就会失败的CI门禁才是问责机制。 </objective>

Quick Route

快速指引

You need to...Go to
Test backend capacity / throughput / latency under traffick6 Load Testing
references/recipes.md
Pick a load shape (constant / ramp / spike / soak)Load Profiles table
Measure frontend speed for real users (LCP, INP, CLS)Web Performance + Core Web Vitals
Gate page perf in CILighthouse CI (gate TBT, not INP — see below)
A budget is breached and you must find whyBottleneck Identification
Migrate an existing suite from k6 v1 → v2k6 v2 Migration callout
你需要...前往
测试流量下后端的容量/吞吐量/延迟k6负载测试
references/recipes.md
选择负载模式(恒定/渐变/峰值/浸泡)负载配置文件表格
衡量真实用户的前端速度(LCP、INP、CLS)Web性能 + Core Web Vitals
在CI中管控页面性能Lighthouse CI(管控TBT,而非INP——见下文)
预算已被突破,需查找原因瓶颈识别
将现有测试套件从k6 v1迁移至v2k6 v2迁移提示

Discovery Questions

调研问题

Check
.agents/qa-project-context.md
first — if it exists, use it and skip questions already answered there.
首先查看
.agents/qa-project-context.md
——若存在,使用其中内容并跳过已回答的问题。

What to Measure

测量对象

  • Web performance or load testing? Web performance measures user-perceived speed (Core Web Vitals, page load). Load testing measures server capacity (RPS, latency under load). Most products need both.
  • Which user journeys are performance-critical? Not every endpoint needs load testing. Focus on high-traffic, revenue-critical, or latency-sensitive flows.
  • Existing performance budgets? If yes, what are the targets? If no, this skill helps establish them — measure baseline first.
  • Web性能测试还是负载测试? Web性能测试衡量用户感知的速度(Core Web Vitals、页面加载)。负载测试衡量服务器容量(RPS、负载下的延迟)。大多数产品两者都需要。
  • 哪些用户旅程对性能至关重要?并非每个端点都需要负载测试。重点关注高流量、影响营收或对延迟敏感的流程。
  • 是否已有性能预算?如果有,目标是什么?如果没有,本技能可帮助建立预算——先测量基准值。

Current State

当前状态

  • What is the current baseline? You need numbers before you can set targets. Measure first, then define budgets.
  • What broke due to performance before? Slow pages that lost users, endpoints that timed out under load, queries that locked up — these point at where to focus.
  • Existing monitoring? APM (Datadog, New Relic), RUM, or synthetic probes give you field data to model realistic load.
  • 当前基准值是多少?在设定目标前你需要有数据。先测量,再定义预算。
  • 之前因性能问题出过哪些故障?导致用户流失的慢页面、负载下超时的端点、锁死的查询——这些指出了需要关注的重点。
  • 是否已有监控?APM(Datadog、New Relic)、RUM或合成探测工具可为你提供真实负载建模的现场数据。

Infrastructure

基础设施

  • Where does load testing run? Target staging or a dedicated load-test environment, never production without explicit operations coordination.
  • Expected traffic pattern? Steady, daily peaks, seasonal spikes (Black Friday), or event-driven bursts — this picks the load profile.
  • Rate limits, WAF rules, or auto-scaling in the path? These distort results and must be accounted for in test design.
  • 负载测试在哪里运行?目标环境为预发布环境或专用负载测试环境,未经运维明确协调绝不能在生产环境运行。
  • 预期流量模式是什么?稳定流量、每日峰值、季节性峰值(如黑色星期五)或事件驱动的突发流量——这决定了负载配置文件的选择。
  • 路径中是否有速率限制、WAF规则或自动扩缩容?这些会扭曲测试结果,必须在测试设计中加以考虑。

Core Principles

核心原则

1. Measure before optimizing

1. 先测量再优化

Performance intuition is unreliable; developers routinely optimize the wrong thing. Profile first, identify the actual bottleneck, then optimize. A profiled 50ms win in the right place beats an assumed 500ms win in the wrong one.
性能直觉不可靠;开发人员经常优化错误的点。先分析性能,识别实际瓶颈,再进行优化。在正确的地方获得50毫秒的提升,远胜于在错误的地方臆想500毫秒的优化效果。

2. Budgets are only real if CI enforces them

2. 只有被CI强制执行的预算才是真实有效的

A budget documented in a wiki but not checked in CI is violated within weeks. Wire budgets into the pipeline as k6 thresholds and Lighthouse assertions so regressions fail the build, not a quarterly review.
记录在维基文档中但未在CI中检查的预算,几周内就会被违反。将预算作为k6阈值和Lighthouse断言集成到流水线中,这样性能回归会直接导致构建失败,而非等到季度评审才发现。

3. Realistic load beats maximum stress

3. 真实负载优于极限压力测试

A stress test to 10x traffic tells you the breaking point. A load test at 1.5x expected traffic tells you whether tomorrow's real users have a good experience. Both have value, but realistic load runs more often and catches regressions earlier.
将流量提升至10倍的压力测试能告诉你系统的崩溃点。而基于预期流量1.5倍的负载测试,能告诉你明天的真实用户是否有良好体验。两者都有价值,但真实负载测试更常运行,能更早发现回归问题。

4. Core Web Vitals are what users actually feel

4. Core Web Vitals是用户实际感知到的性能

Server-side metrics (latency, throughput) matter, but users experience performance through the browser. LCP, INP, and CLS measure perceived speed. A fast API that renders slowly is still slow to users.
服务器端指标(延迟、吞吐量)很重要,但用户是通过浏览器体验性能的。LCP、INP和CLS衡量的是感知速度。一个快速的API如果渲染缓慢,对用户来说仍然是慢的。

5. Performance is a feature

5. 性能是一项功能

It does not happen by accident. It needs dedicated test infrastructure, budgets, and monitoring, and the same continuous attention as functional correctness. Treat a performance regression with the same urgency as a functional bug.
它不会偶然出现。它需要专用的测试基础设施、预算和监控,以及与功能正确性同等持续的关注。对待性能回归要像对待功能bug一样紧急。

k6 Load Testing

k6负载测试

k6 is an open-source load testing tool that uses JavaScript/TypeScript for scripts, runs from the CLI, and integrates with CI. Current stable: k6 v2.0.0 (final shipped 2026-05). v2 has breaking changes from v1 — see the migration callout below.
A load test is built from three pieces: a load profile (the
stages
/
scenarios
shape), checks (per-request assertions), and thresholds (pass/fail budgets that set the exit code). Always drive the base URL from
__ENV
so the same script runs against local, staging, and CI.
See
references/recipes.md
for the full basic load test, custom metrics, and scenarios. A minimal threshold block:
javascript
export const options = {
  stages: [
    { duration: '1m', target: 20 },
    { duration: '3m', target: 20 },
    { duration: '1m', target: 0 },
  ],
  thresholds: {
    http_req_duration: ['p(95)<500', 'p(99)<1000'],
    http_req_failed: ['rate<0.01'],
  },
};
k6是一款开源负载测试工具,使用JavaScript/TypeScript编写脚本,通过CLI运行,并可与CI集成。当前稳定版本:k6 v2.0.0(最终发布于2026年5月)。v2相较于v1有破坏性变更——见下文的迁移提示。
负载测试由三部分构成:负载配置文件
stages
/
scenarios
的模式)、检查项(每个请求的断言)和阈值(决定退出码的通过/失败预算)。始终从
__ENV
获取基准URL,以便同一脚本可在本地、预发布和CI环境中运行。
完整的基础负载测试、自定义指标和场景示例请参见
references/recipes.md
。一个最小化阈值块示例:
javascript
export const options = {
  stages: [
    { duration: '1m', target: 20 },
    { duration: '3m', target: 20 },
    { duration: '1m', target: 0 },
  ],
  thresholds: {
    http_req_duration: ['p(95)<500', 'p(99)<1000'],
    http_req_failed: ['rate<0.01'],
  },
};

Load Profiles

负载配置文件

ProfileQuestionShapeDuration
ConstantCan the system handle normal traffic?
vus: 50, duration: '10m'
10 min
Ramp-up (stress)At what point does it degrade?50 → 100 → 200 → 400 → 800 → 012 min
SpikeDoes it recover from a sudden surge?50 → spike 500 → sustain → drop 50 → recover6 min
SoakDoes it leak resources over time?Ramp to 100, sustain 4h, ramp down4+ hours
A spike test is not done until "does it recover?" is an assertion, not a comment. Tag the post-spike window (e.g.
phase:recovery
) and scope a threshold to it so the run fails if p95 stays elevated. See the recovery-detection recipe in
references/recipes.md
.
配置文件适用问题模式时长
恒定负载系统能否处理正常流量?
vus: 50, duration: '10m'
10分钟
渐变上升(压力测试)系统在什么点开始性能下降?50 → 100 → 200 → 400 → 800 → 012分钟
峰值测试系统能否从突发流量中恢复?50 → 峰值500 → 持续 → 降至50 → 恢复6分钟
浸泡测试系统是否会随时间泄漏资源?渐变至100,持续4小时,再渐变下降4小时以上
峰值测试必须将“能否恢复”作为断言,而非注释。标记峰值后的阶段(如
phase:recovery
)并为该阶段设置阈值,若p95延迟仍居高不下则测试失败。请参见
references/recipes.md
中的恢复检测示例。

Custom Metrics and Scenarios

自定义指标与场景

k6 has four metric types:
Counter
(cumulative count),
Rate
(proportion of non-zero/true values, 0..1),
Trend
(statistical distribution — p50/p95/p99),
Gauge
(latest value). Tag requests with
{ tags: { name: 'endpoint' } }
to filter metrics per endpoint, scenario, or flow.
Scenarios run distinct user flows concurrently, each with its own executor and per-scenario thresholds (
'http_req_duration{scenario:checkout}': ['p(95)<500']
). Use them to model a real mix — browsers + checkout + API-heavy load at once. Full custom-metric and scenario examples are in
references/recipes.md
.
k6有四种指标类型:
Counter
(累计计数)、
Rate
(非零/真值的比例,0到1)、
Trend
(统计分布——p50/p95/p99)、
Gauge
(最新值)。使用
{ tags: { name: 'endpoint' } }
标记请求,以便按端点、场景或流程过滤指标。
场景可同时运行不同的用户流程,每个流程有自己的执行器和场景专属阈值(如
'http_req_duration{scenario:checkout}': ['p(95)<500']
)。使用场景可模拟真实流量组合——浏览器流量+结账流程+API密集型负载同时运行。完整的自定义指标和场景示例请参见
references/recipes.md

k6 CI Integration

k6 CI集成

Install k6 with the official
grafana/setup-k6-action@v1
— not a hand-rolled apt/gpg keyserver block (brittle, rots, no version pin). k6 exits non-zero when any threshold is breached, so a breached budget fails the job with no extra wiring. The full GitHub Actions workflow (checkout → setup-k6 → run → upload artifact) is in
references/recipes.md
.
k6 v1 → v2 migration (v2.0.0 final, 2026-05):
  • k6/experimental/websockets
    k6/websockets
    (drop the
    experimental/
    prefix; stable now)
  • k6/experimental/redis
    k6/x/redis
    — NOT removed. The import auto-resolves the
    xk6-redis
    extension (auto-extension-resolution is on by default; JS usage unchanged). Do not hand-roll a Redis client.
  • externally-controlled
    executor removed
  • options.ext.loadimpact
    removed → use
    options.cloud
    (Grafana Cloud k6, formerly k6 Cloud / Load Impact)
  • CLI:
    --no-summary
    --summary-mode=disabled
    ;
    --upload-only
    k6 cloud upload script.js
    ;
    k6 login
    /
    pause
    /
    resume
    /
    scale
    /
    status
    removed (use
    k6 cloud login
    , etc.); positional
    k6 cloud script.js
    removed
  • Exit code 97 is new: a non-threshold cloud-side abort. Wire it into CI handling. Reference: https://grafana.com/docs/k6/latest/get-started/migrating-to-v2/
使用官方的**
grafana/setup-k6-action@v1
**安装k6——不要手动编写apt/gpg密钥服务器代码块(脆弱、易失效、无法固定版本)。当任何阈值被突破时,k6会返回非零退出码,因此预算被突破会直接导致任务失败,无需额外配置。完整的GitHub Actions工作流(检出代码→安装k6→运行测试→上传产物)请参见
references/recipes.md
k6 v1 → v2迁移(v2.0.0最终版,2026年5月):
  • k6/experimental/websockets
    k6/websockets
    (移除
    experimental/
    前缀;现已稳定)
  • k6/experimental/redis
    k6/x/redis
    ——未被移除。该导入会自动解析
    xk6-redis
    扩展(自动扩展解析默认开启;JS用法不变)。请勿手动编写Redis客户端。
  • 移除
    externally-controlled
    执行器
  • 移除
    options.ext.loadimpact
    → 使用
    options.cloud
    (Grafana Cloud k6,前身为k6 Cloud / Load Impact)
  • CLI:
    --no-summary
    --summary-mode=disabled
    --upload-only
    k6 cloud upload script.js
    k6 login
    /
    pause
    /
    resume
    /
    scale
    /
    status
    已移除(请使用
    k6 cloud login
    等);位置参数
    k6 cloud script.js
    已移除
  • 新增退出码97:非阈值相关的云端中止。需在CI处理中适配该退出码。 参考文档:https://grafana.com/docs/k6/latest/get-started/migrating-to-v2/

Web Performance

Web性能

Lighthouse CI

Lighthouse CI

Lighthouse CI (
@lhci/cli
) automates Google Lighthouse audits and enforces budgets in the pipeline via
lighthouserc.js
assertions. Current:
@lhci/cli
0.15.x on the Lighthouse 12.6 engine. The project is in maintenance mode (last release ~a year ago) and does not yet support Lighthouse 13 (needs Node 22.19+); it remains the standard CI surface for Lighthouse, but watch upstream before adopting in greenfield projects.
The full
lighthouserc.js
(LCP/CLS/TBT/perf-score assertions) and the
lhci autorun
CI step are in
references/recipes.md
.
Lighthouse CI(
@lhci/cli
)可自动执行Google Lighthouse审计,并通过
lighthouserc.js
中的断言在流水线中强制执行预算。当前版本:基于Lighthouse 12.6引擎的
@lhci/cli
0.15.x。该项目处于维护模式(上次发布约一年前),尚不支持Lighthouse 13(需要Node 22.19+);它仍是Lighthouse的标准CI集成方案,但在新项目中采用前需关注上游动态。
完整的
lighthouserc.js
(包含LCP/CLS/TBT/性能得分断言)和
lhci autorun
CI步骤示例请参见
references/recipes.md

INP is field-only — gate TBT in the lab

INP仅适用于现场数据——在实验室环境中管控TBT

This is the single most-misunderstood point in web perf, so be precise:
  • INP (Interaction to Next Paint) is a field-only metric. A Lighthouse lab audit loads a page with no user interaction, so it cannot measure or score INP. Asserting
    interaction-to-next-paint
    in a standard
    lhci autorun
    run gates something Lighthouse never produces.
  • In the lab, gate Total Blocking Time (TBT) as the proxy: assert
    'total-blocking-time': ['error', { maxNumericValue: 200 }]
    . TBT correlates with INP but is not identical (a page can hit 0ms TBT and still fail field INP).
  • Track real INP from the field — Chrome UX Report (CrUX) or your RUM tool. That is the number users actually experience and the one Google ranks on.
  • Only if you must measure scripted-interaction latency, use Lighthouse user-flow / timespan mode with scripted clicks, or
    k6/browser
    with a
    PerformanceObserver
    on
    event
    entries. Treat that as a scripted lab proxy, still not field INP.
FID is gone: FID was deprecated and
web-vitals
v5+ removed it; INP became a Core Web Vital in March 2024. Do not assert on FID in any new code.
这是Web性能领域最容易被误解的点,请务必明确:
  • INP(Interaction to Next Paint,交互到下一次绘制)是仅适用于现场的指标。 Lighthouse实验室审计加载页面时无用户交互,因此无法测量或评分INP。在标准
    lhci autorun
    运行中断言
    interaction-to-next-paint
    ,实际上是在管控一个Lighthouse从未生成过的数值。
  • 在实验室环境中,管控Total Blocking Time(TBT,总阻塞时间)作为替代指标:断言
    'total-blocking-time': ['error', { maxNumericValue: 200 }]
    。TBT与INP相关但并不完全相同(页面可能TBT为0毫秒但现场INP不达标)。
  • 从现场数据跟踪真实INP——使用Chrome UX Report(CrUX)或你的RUM工具。这才是用户实际体验到的数值,也是Google排名所依据的指标。
  • 若必须测量脚本化交互延迟,请使用Lighthouse用户流程/时间段模式配合脚本化点击,或使用
    k6/browser
    并通过
    PerformanceObserver
    监听
    event
    条目。这仅作为脚本化实验室替代方案,仍不是现场INP。
FID已被移除: FID已被弃用,
web-vitals
v5+版本已移除该指标;INP于2024年3月成为Core Web Vital。请勿在任何新代码中断言FID。

Measuring CWV in Playwright

在Playwright中测量CWV

For a per-page lab check inside your existing Playwright suite, use
page.evaluate
with a
PerformanceObserver
to capture LCP and CLS (both observe cleanly on page load), then assert the thresholds. Full test in
references/recipes.md
. For under-load CWV capture, use the
k6/browser
recipe in the same file.
若要在现有Playwright套件中对单个页面进行实验室检查,可使用
page.evaluate
配合
PerformanceObserver
捕获LCP和CLS(两者均可在页面加载时清晰观测),然后断言阈值。完整测试示例请参见
references/recipes.md
。若要在负载下捕获CWV,请使用同一文档中的
k6/browser
示例。

Core Web Vitals

Core Web Vitals

The three metrics Google uses for user-perceived performance.
MetricMeasuresGoodNeeds ImprovementPoor
LCP (Largest Contentful Paint)Loading — when the largest element renders≤ 2.5s2.5s–4.0s> 4.0s
INP (Interaction to Next Paint)Responsiveness — interaction → next paint (field-only)≤ 200ms200ms–500ms> 500ms
CLS (Cumulative Layout Shift)Visual stability — unexpected layout movement≤ 0.10.1–0.25> 0.25
Common fixes:
  • LCP — slow server (cache/CDN, SSR/SSG the LCP content), render-blocking CSS/JS (defer, inline critical CSS), slow image load (WebP/AVIF,
    preload
    the LCP image).
  • INP — long JS tasks (
    scheduler.yield()
    ,
    requestIdleCallback
    ), heavy handlers (debounce/throttle, Web Workers), layout thrashing (batch DOM reads/writes via
    requestAnimationFrame
    ).
  • CLS — set
    width
    /
    height
    on images, reserve space for injected content (
    aspect-ratio
    /
    min-height
    ),
    font-display: swap
    with
    size-adjust
    , fixed-size containers for ads/embeds.
Google用于衡量用户感知性能的三项指标。
指标衡量内容良好需要改进较差
LCP(Largest Contentful Paint,最大内容绘制)加载性能——最大元素完成渲染的时间≤ 2.5秒2.5秒–4.0秒> 4.0秒
INP(Interaction to Next Paint,交互到下一次绘制)响应性能——交互到下一次绘制的时间(仅适用于现场)≤ 200毫秒200毫秒–500毫秒> 500毫秒
CLS(Cumulative Layout Shift,累积布局偏移)视觉稳定性——意外的布局移动≤ 0.10.1–0.25> 0.25
常见修复方案:
  • LCP ——优化慢服务器(缓存/CDN、对LCP内容使用SSR/SSG)、减少阻塞渲染的CSS/JS(延迟加载、内联关键CSS)、优化慢图片加载(使用WebP/AVIF格式、
    preload
    LCP图片)。
  • INP ——拆分长JS任务(使用
    scheduler.yield()
    requestIdleCallback
    )、优化重型处理函数(防抖/节流、使用Web Workers)、避免布局抖动(通过
    requestAnimationFrame
    批量DOM读写)。
  • CLS ——为图片设置
    width
    /
    height
    、为注入内容预留空间(使用
    aspect-ratio
    /
    min-height
    )、使用
    font-display: swap
    配合
    size-adjust
    、为广告/嵌入内容使用固定尺寸容器。

Field vs. Lab Data

现场数据 vs 实验室数据

Lab DataField Data
SourceLighthouse, WebPageTest, Playwright, k6/browserChrome UX Report (CrUX), RUM tools
EnvironmentSimulated, controlledReal users, real devices, real networks
Use forDebugging, CI gates, pre-deploymentUnderstanding actual user experience
LimitationNo real-world variance; no field INPCannot reproduce specific conditions
Use lab data for CI gates and debugging; use field data to understand the real user experience. A page that scores 100 in Lighthouse but has poor CrUX data has a real problem — and INP only ever shows up in the field column.
实验室数据现场数据
来源Lighthouse、WebPageTest、Playwright、k6/browserChrome UX Report(CrUX)、RUM工具
环境模拟、受控真实用户、真实设备、真实网络
用途调试、CI门禁、预部署检查了解实际用户体验
局限性无真实环境差异;无法获取现场INP无法重现特定场景
使用实验室数据进行CI门禁和调试;使用现场数据了解真实用户体验。一个在Lighthouse中得分为100但CrUX数据较差的页面,确实存在真实问题——而且INP只会出现在现场数据中。

Bottleneck Identification

瓶颈识别

When a budget is breached, investigate in this order — never guess, never optimize before profiling:
  1. Identify the slow endpoint. Per-endpoint
    Trend
    metrics in k6 give p50/p95/p99 per API. The slowest is the first target.
  2. Database. Check missing indexes (
    EXPLAIN
    ), N+1 patterns (JOIN/batch), lock contention on write-heavy tables (optimize transactions), unbounded result sets (paginate).
  3. CDN/caching. Verify
    cache-control
    on static assets (
    public, max-age=31536000, immutable
    ) and the
    x-cache: HIT
    rate.
  4. Third-party scripts. Run Lighthouse with
    blockedUrlPatterns
    for analytics/chat/tracking; compare scores with and without to quantify the cost.
  5. Correlate with server metrics. Client-side latency alone hides the cause — check CPU, memory, disk I/O, connection-pool saturation, and query execution time during the run.
当预算被突破时,按以下顺序排查——绝不猜测,绝不在分析性能前进行优化:
  1. 识别慢端点。 k6中的端点级
    Trend
    指标可提供每个API的p50/p95/p99延迟。最慢的端点是首要排查目标。
  2. 数据库。 检查缺失的索引(使用
    EXPLAIN
    )、N+1查询模式(使用JOIN/批量查询)、写密集型表的锁竞争(优化事务)、无限制结果集(分页)。
  3. CDN/缓存。 验证静态资源的
    cache-control
    设置(
    public, max-age=31536000, immutable
    )和
    x-cache: HIT
    命中率。
  4. 第三方脚本。 使用
    blockedUrlPatterns
    在Lighthouse中屏蔽分析/聊天/跟踪脚本;对比屏蔽前后的得分,量化其性能影响。
  5. 关联服务器指标。 仅看客户端延迟无法找到根本原因——检查测试运行期间的CPU、内存、磁盘I/O、连接池饱和度和查询执行时间。

Anti-Patterns

反模式

1. Load testing production without coordination

1. 未经协调在生产环境运行负载测试

Load tests can trigger auto-scaling (expensive), rate limiting (test fails), alerts (unnecessary pages), or outages. Always coordinate with operations and target staging or a dedicated load-test environment.
负载测试可能触发自动扩缩容(成本高昂)、速率限制(测试失败)、告警(不必要的通知)或服务中断。务必与运维协调,目标环境为预发布或专用负载测试环境。

2. Unrealistic load scenarios

2. 不切实际的负载场景

Testing 10,000 concurrent users when the product has 500 DAU, or uniform traffic when real traffic has peaks. Model load from analytics; absent that, start at 2x estimated peak and increase.
当产品日活用户仅500时,测试10000并发用户;或当真实流量存在峰值时,使用均匀流量测试。根据分析数据建模负载;若无分析数据,从预估峰值的2倍开始测试并逐步增加。

3. Ignoring server-side metrics

3. 忽略服务器端指标

Looking only at k6's client-side response times. The server may be at 95% CPU, the connection pool exhausted, or memory leaking. Correlate load results with server metrics.
仅关注k6的客户端响应时间。服务器可能处于95% CPU使用率、连接池耗尽或内存泄漏状态。需将负载测试结果与服务器指标关联分析。

4. Performance testing only before releases

4. 仅在发布前进行性能测试

A quarterly pre-release load test lets dozens of regressions accumulate with untraceable root causes. Run in CI on every merge to main with budgets that catch regressions immediately.
每季度一次的发布前负载测试会让大量回归问题累积,且无法追踪根本原因。应在每次合并到主分支时都在CI中运行性能测试,通过预算及时发现回归问题。

5. No performance budgets

5. 无性能预算

"LCP is 3.2s" is information; "LCP must be under 2.5s" is a gate. Define budgets, enforce them as k6 thresholds and Lighthouse assertions, and treat violations as bugs.
“LCP为3.2秒”只是信息;“LCP必须低于2.5秒”才是门禁。定义预算,将其作为k6阈值和Lighthouse断言强制执行,并将预算违反视为bug处理。

6. Asserting INP in standard Lighthouse CI

6. 在标准Lighthouse CI中断言INP

Standard
lhci autorun
lab mode cannot produce an INP audit — no user interaction. Gating
interaction-to-next-paint
there gates a number Lighthouse never measures. Gate
total-blocking-time
as the lab proxy and track real INP from CrUX/RUM.
标准
lhci autorun
实验室模式无法生成INP审计结果——无用户交互。在此处管控
interaction-to-next-paint
,实际上是在管控一个Lighthouse从未测量过的数值。应管控
total-blocking-time
作为实验室替代指标,并从CrUX/RUM跟踪真实INP。

7. Optimizing without profiling

7. 未分析性能就进行优化

Spending days on a function that is 2% of response time. Profile, find the actual bottleneck, then optimize. The 200ms query beats the 5ms JS function every time.
花费数天优化一个仅占响应时间2%的函数。先分析性能,找到实际瓶颈,再进行优化。200毫秒的查询优化远胜于5毫秒的JS函数优化。

8. Testing with empty databases

8. 使用空数据库进行测试

Load testing against 100 seeded rows when production has 10 million. Query performance is radically different at scale. Seed the load-test environment with production-scale (anonymized) data first.
当生产环境有1000万条数据时,仅用100条种子数据进行负载测试。查询性能在不同数据规模下差异极大。负载测试环境需先导入与生产规模相当的(匿名化)数据。

Verification

验证

Prove the artifacts actually work before claiming done:
  • k6 script:
    k6 run --summary-mode=disabled load-tests/api-load.js
    exits 0 and the end-of-test summary shows every
    thresholds
    line green (
    ). A red threshold line means a breached budget and a non-zero exit.
  • Spike recovery: run the spike script and confirm the
    {phase:recovery}
    threshold appears in the summary and passes — proving recovery is asserted, not just commented.
  • Lighthouse CI:
    lhci autorun
    exits 0 with all
    ['error', ...]
    assertions passing; a breached LCP/CLS/TBT assertion exits non-zero.
在完成前需证明产物确实有效:
  • k6脚本:
    k6 run --summary-mode=disabled load-tests/api-load.js
    返回0,且测试结束摘要显示所有
    thresholds
    行均为绿色(
    )。红色阈值行表示预算被突破,返回非零退出码。
  • 峰值恢复: 运行峰值测试脚本,确认
    {phase:recovery}
    阈值出现在摘要中并通过——证明恢复已被断言,而非仅注释。
  • Lighthouse CI:
    lhci autorun
    返回0,所有
    ['error', ...]
    断言均通过;若LCP/CLS/TBT断言被突破,则返回非零退出码。

Done When

完成标准

  • k6 scripts cover the target load profiles: baseline (constant), stress (ramp to breaking point), and soak (sustained), each with
    __ENV
    -driven base URL.
  • Spike test asserts recovery via a threshold scoped to the post-spike window (e.g.
    http_req_duration{phase:recovery}
    ), not just a
    // recovery
    comment.
  • Performance budgets encoded as k6 thresholds (e.g.
    p(95)<500
    ,
    http_req_failed rate<0.01
    ) that fail the CI job when exceeded.
  • Lighthouse CI
    lighthouserc.js
    gates merges on
    largest-contentful-paint
    ,
    cumulative-layout-shift
    , and
    total-blocking-time
    (the lab proxy for INP) as
    ['error', ...]
    assertions; real INP tracked from CrUX/RUM, not asserted in lab.
  • Core Web Vitals baselines documented for each key page (home, checkout, dashboard) with Good/Needs Improvement/Poor classification.
  • Test results include p95 and p99 latency, error rate, and throughput per scenario, stored as CI artifacts.
  • k6脚本覆盖目标负载配置文件:基准(恒定)、压力(渐变至崩溃点)和浸泡(持续),且均使用
    __ENV
    驱动的基准URL。
  • 峰值测试通过针对峰值后阶段的阈值(如
    http_req_duration{phase:recovery}
    )断言恢复能力,而非仅添加
    // recovery
    注释。
  • 性能预算被编码为k6阈值(如
    p(95)<500
    http_req_failed rate<0.01
    ),当预算被突破时CI任务失败。
  • Lighthouse CI的
    lighthouserc.js
    largest-contentful-paint
    cumulative-layout-shift
    total-blocking-time
    (INP的实验室替代指标)作为
    ['error', ...]
    断言管控合并操作;真实INP从CrUX/RUM跟踪,不在实验室中断言。
  • 已记录每个关键页面(首页、结账页、仪表盘)的Core Web Vitals基准值,并进行了良好/需要改进/较差的分类。
  • 测试结果包含每个场景的p95和p99延迟、错误率及吞吐量,并作为CI产物存储。

Reference Files (in
references/
)

参考文件(位于
references/
目录)

  • recipes.md — runnable artifacts: basic k6 load test, spike-with-recovery detection, custom metrics, scenarios, k6 CI workflow (
    grafana/setup-k6-action
    ),
    lighthouserc.js
    , the
    k6/browser
    CWV-under-load example, and the Playwright LCP/CLS test.
  • recipes.md ——可运行的产物示例:基础k6负载测试、带恢复检测的峰值测试、自定义指标、场景、k6 CI工作流(
    grafana/setup-k6-action
    )、
    lighthouserc.js
    、负载下CWV测量的
    k6/browser
    示例,以及Playwright LCP/CLS测试。

Related Skills

相关技能

  • ci-cd-integration — pipeline wiring for k6 and Lighthouse CI, scheduling nightly runs, gating deployments on budgets.
  • qa-metrics — LCP/INP/CLS and p95 latency as part of the broader QA metrics dashboard.
  • release-readiness — performance benchmarks in the go/no-go checklist.
  • synthetic-monitoring — scheduled production CWV/uptime probes after release; this skill is pre-release lab gating.
  • observability-driven-testing — when prod telemetry is the input to designing new perf tests.
  • qa-project-context — captures performance budgets, traffic patterns, and critical flows to test.
  • ci-cd-integration ——k6和Lighthouse CI的流水线配置、夜间测试调度、基于预算管控部署。
  • qa-metrics ——将LCP/INP/CLS和p95延迟纳入更广泛的QA指标仪表盘。
  • release-readiness ——将性能基准纳入发布准入 checklist。
  • synthetic-monitoring ——发布后对生产环境进行定期CWV/可用性探测;本技能针对预发布阶段的实验室管控。
  • observability-driven-testing ——当生产遥测作为设计新性能测试的输入时使用。
  • qa-project-context ——记录性能预算、流量模式及需测试的关键流程。