性能监控与优化
Mizuki 围绕静态站点构建产物建立了一套自动化的性能监控与回归检测机制:以 Lighthouse CI 为核心采集性能指标,以 performance-baseline.json 作为回归基线,并通过 GitHub Actions 在每次推送时自动执行检查。本页说明该能力的组成、配置、工作流程与运维注意事项。
Purpose and Scope
本页覆盖 Mizuki 中"性能监控与优化"这一运维能力的完整闭环:
- Lighthouse CI 的采集与断言配置(
lighthouserc.json) - 性能基准(baseline)的建立、查看与更新
- 性能回归(regression)的检测逻辑与告警输出
- GitHub Actions 中的自动化性能检查流水线
- 运行时性能监控层(Web Vitals / Performance Observer)在体系中的定位
- 常见故障排查与波动治理手段
以下内容不在本页范围内,属于兄弟页面/独立主题:
- 站点的构建、部署与发布流水线整体说明(见部署与运维相关页面)
- 图片懒加载、缓存等代码级优化实现(README 中作为功能列出,属于站点实现范畴)
- SEO、sitemap、RSS 等与性能无直接关系的站点能力
Overview
Mizuki 是一个 Astro 静态博客主题项目。静态站点的性能问题通常在构建产物与页面渲染阶段产生(包体积、图片体积、字体加载、布局偏移等),因此项目的性能监控设计为构建后、发布前的门禁式检查,而非线上 APM:
| 工具 | 用途 |
|---|---|
| Lighthouse CI | 自动化性能测试 |
| Web Vitals | 运行时性能监控 |
| Performance Observer | 自定义指标收集 |
配套的性能指标目标为:
| 指标 | 目标值 | 说明 |
|---|---|---|
| Performance Score | ≥ 0.85 | Lighthouse 性能分数 |
| FCP | ≤ 2000ms | 首次内容绘制 |
| LCP | ≤ 4000ms | 最大内容绘制 |
| TTI | ≤ 5000ms | 可交互时间 |
| CLS | ≤ 0.1 | 累积布局偏移 |
整体工作方式:
pnpm build构建产物;pnpm lhci autorun自动启动 preview server(端口 4321)并对配置的页面列表采样;- 断言阶段对关键指标做阈值检查(只警告不阻断);
- 详细报告落盘到
.lighthouseci/; - 基准脚本把指标固化为
performance-baseline.json,回归脚本据此检测超过 10% 的性能退化。
设计意图是**"警告优先、基线对比"**:CI 中的性能检查标记为 ⚠️(warning)而非硬失败,避免运行环境波动直接打断开发流程;真正的回归判定交给"相对自身历史基线"的对比,而不是绝对阈值,这样对慢速 CI 机器更宽容。
Architecture
各组成部分的角色:
lighthouserc.json:Lighthouse CI 的主配置文件,定义采样页面、运行次数与断言阈值,是本地与 CI 两条路径共用的单一事实来源。- Preview server(localhost:4321):
lhci autorun会自动启动它;这也是排查"端口占用"问题的根源(见失败模式一节)。 .lighthouseci/目录:每次运行的 Lighthouse 结果(LHR,Lighthouse Result JSON)落盘位置,是基准脚本与回归脚本的数据输入。performance-baseline.json:按页面(如homepage)组织的指标基线,附带thresholds.regressionPercent回归容忍度。src/utils/performance-observer.ts:仓库中存在的运行时性能观测工具文件(文档中"自定义指标收集"的实现载体)。其内部实现细节未在本次核验中读取,本页不对该文件内部 API 做逐行说明。
注意一个重要的仓库现状:文档引用了
scripts/performance-baseline.js与scripts/performance-check.js两个管理命令,但当前的scripts/目录清单中并未包含这两个文件。本页如实记录该差异——命令契约以docs/PERFORMANCE_MONITORING.md的描述为准,实际脚本可能尚未提交或已移除,使用前请以仓库当前状态为准。
运行时监控层
文档把监控体系分为两层:
- 构建后门禁层(Lighthouse CI):模拟加载页面、计算 FCP/LCP/TTI/CLS 等聚合指标,用于回归判定。这是本页主体。
- 运行时层(Web Vitals / Performance Observer):在真实浏览器中收集用户侧指标。仓库中的对应文件是
src/utils/performance-observer.ts(通过文件名匹配确认存在),文档将其定位为"自定义指标收集"。
分层的意图:Lighthouse 是受控环境下的一致性测量,适合做 CI 对比;Web Vitals/Performance Observer 反映真实用户设备的分布,适合发现环境相关问题。两者的指标口径(FCP/LCP/CLS)保持一致,便于互相印证。
Core Flow
以一次"提交代码 → 性能检查 → 回归判定"的完整流程为例:
流程顺序的设计理由:
- 先构建再测量:Lighthouse 必须针对产物运行,因此
pnpm build是前置步骤;CI 中两者顺序固定。 - 多次采样取稳定值:
numberOfRuns: 3用于抑制单次运行的抖动;波动仍大时文档建议提高到 5 次、改用中位数或放宽阈值。 - 断言只 warn 不 fail:
categories:performance与first-contentful-paint的断言级别都是warn,对应 CI 里 Lighthouse 检查显示为 ⚠️,与其余三项硬检查(Astro Check ✅、ESLint ✅、Build ✅)形成明确的阻断/非阻断分层。 - 回归判定与 CI 解耦:绝对阈值放 CI,相对(10%)回归对比放本地脚本,避免"机器变慢"被误判为"代码变慢"。
Usage Examples
运行完整性能测试
1# 构建项目
2pnpm build
3
4# 运行 Lighthouse CI(自动启动 preview server)
5pnpm lhci autorunSource: docs/PERFORMANCE_MONITORING.md
建立与更新性能基准
1# 查看当前性能指标(不更新基准)
2node scripts/performance-baseline.js
3
4# 更新性能基准
5node scripts/performance-baseline.js --update
6
7# 检查性能回归
8node scripts/performance-check.jsSource: docs/PERFORMANCE_MONITORING.md
Lighthouse CI 主配置(节选自项目文档中的 lighthouserc.json 内容)
1{
2 "ci": {
3 "collect": {
4 "numberOfRuns": 3,
5 "url": [
6 "http://localhost:4321/",
7 "http://localhost:4321/about/",
8 "http://localhost:4321/anime/"
9 ]
10 },
11 "assert": {
12 "assertions": {
13 "categories:performance": ["warn", { "minScore": 0.85 }],
14 "first-contentful-paint": ["warn", { "maxNumericValue": 2000 }]
15 }
16 }
17 }
18}Source: docs/PERFORMANCE_MONITORING.md
CI 中的 Lighthouse 工作流(.github/workflows/lighthouse.yml 内容)
1name: Lighthouse CI
2on: [push, pull_request]
3jobs:
4 lighthouse:
5 runs-on: ubuntu-latest
6 steps:
7 - uses: actions/checkout@v6
8 - run: pnpm install
9 - run: pnpm build
10 - uses: treosh/lighthouse-ci-action@v11
11 with:
12 configPath: "./lighthouserc.json"
13 uploadArtifacts: true
14 temporaryPublicStorage: trueSource: docs/PERFORMANCE_MONITORING.md
基线文件结构(performance-baseline.json)
1{
2 "baseline": {
3 "homepage": {
4 "url": "http://localhost:4321/",
5 "metrics": {
6 "performance": 0.85,
7 "first-contentful-paint": 1800,
8 "largest-contentful-paint": 3500
9 }
10 }
11 },
12 "thresholds": {
13 "regressionPercent": 10
14 }
15}Source: docs/PERFORMANCE_MONITORING.md
Configuration Options
Lighthouse CI 相关配置项(来自 lighthouserc.json):
| 选项 | 类型 | 默认/示例 | 说明 |
|---|---|---|---|
ci.collect.numberOfRuns | number | 3 | 运行次数,结果取平均值;波动大时可提高到 5 |
ci.collect.url | string[] | ["http://localhost:4321/", "/about/", "/anime/"] | 要测试的页面 URL 列表 |
ci.assert.assertions["categories:performance"] | array | ["warn", { "minScore": 0.85 }] | 性能分数断言:级别 + 最小分数阈值 |
ci.assert.assertions["first-contentful-paint"] | array | ["warn", { "maxNumericValue": 2000 }] | FCP 断言:级别 + 最大毫秒阈值 |
| 断言级别 | string | "warn" | 可设为 "off" 排除检查 |
基线回归配置(来自 performance-baseline.json):
| 选项 | 类型 | 默认/示例 | 说明 |
|---|---|---|---|
baseline.<pageKey>.url | string | http://localhost:4321/ | 基线对应的被测页面 |
baseline.<pageKey>.metrics.performance | number | 0.85 | Lighthouse 性能分数基线 |
baseline.<pageKey>.metrics.first-contentful-paint | number | 1800 | FCP 基线(ms) |
baseline.<pageKey>.metrics.largest-contentful-paint | number | 3500 | LCP 基线(ms) |
thresholds.regressionPercent | number | 10 | 回归告警百分比阈值 |
CI 工作流配置(lighthouse.yml):
| 选项 | 值 | 说明 |
|---|---|---|
on | push, pull_request | 触发时机 |
configPath | ./lighthouserc.json | 复用与本地一致的配置 |
uploadArtifacts | true | 上传报告为构建产物 |
temporaryPublicStorage | true | 使用临时公共存储保存 Lighthouse 报告链接 |
API Reference
本能力不暴露应用代码 API;其接口面是脚本命令与 CLI 参数:
node scripts/performance-baseline.js
无参数时:读取 .lighthouseci/ 中的最新结果,输出当前性能指标摘要,不写基准文件。
参数:
--update(可选):把当前指标写入performance-baseline.json,覆盖既有基线
Returns: 控制台输出的指标摘要;--update 时额外更新基准文件。
node scripts/performance-check.js
对比当前指标与 performance-baseline.json 中基线,任一指标劣化超过 thresholds.regressionPercent(默认 10%)时输出报警块,例如:
1⚠️ Performance regressions detected!
2 ❌ first-contentful-paint
3 Current: 2500.00ms
4 Baseline: 1800.00ms
5 Change: +38.9%Source: docs/PERFORMANCE_MONITORING.md
注意:以上两个脚本文件未出现在当前仓库
scripts/目录清单中,其实现细节(如退出码、是否在 CI 中阻断)未在源码层面核验,此处仅转述文档描述的命令契约。
Failure Modes, Edge Cases & Concurrency
Lighthouse 测试失败的排查
文档给出的标准排查路径:
- 检查网络连接是否正常;
- 确认端口 4321 未被占用(
lhci autorun需要自动启动 preview server,端口冲突会直接失败); - 查看详细错误信息:
npx lhci autorun --verbose。
端口 4321 占用
这是该体系最常见的环境类失败:preview server 端口被残留进程占用会导致 collect 阶段失败。由于配置中的 URL 硬编码为 http://localhost:4321/,处理方式是释放端口而不是改配置。
性能波动(噪声)
单次 Lighthouse 运行天然存在波动,文档给出三种缓解手段:
"numberOfRuns": 5Source: docs/PERFORMANCE_MONITORING.md
配合"使用中位数而非平均值"与"设置更宽松的阈值"两种手段。这也是 numberOfRuns: 3 作为默认值的原因——在置信度与 CI 时长之间取折中。
断言不过但不想阻断
将对应审计项设为 "off" 即可从检查中排除:
"uses-optimized-images": "off",
"uses-webp-images": "off"Source: docs/PERFORMANCE_MONITORING.md
基线漂移
--update 会整体覆盖基线。如果在一个偶发慢速环境下执行 --update,基线会长期偏松,掩盖真实回归。合理做法是只在确认环境稳定、指标可复现时更新基线。
仓库现状差异(重要)
scripts/performance-baseline.js 与 scripts/performance-check.js 未出现在当前 scripts/ 目录清单中(清单实际包含 check-content-pipeline.mjs、check-font-loading.mjs、prepare-fonts.mjs 等)。文档描述的本地基准管理链路目前可能缺少脚本支撑,使用前需确认文件存在,否则回归检测只能依赖 lighthouserc.json 的绝对阈值断言。
并发/一致性
整个采集过程针对静态构建产物,不存在多写者并发问题;唯一的"一致性"约束是 performance-baseline.json 应与被测代码版本同源提交更新,避免基线与代码不同步导致回归判定失真。
Performance & Operational Notes
- CI 成本:每个 PR/推送触发一次 Lighthouse CI;
numberOfRuns: 3× 3 个页面 ≈ 9 次页面采样,是 CI 时长的主要增量来源。 - 报告留存:CI 中
uploadArtifacts: true+temporaryPublicStorage: true保证失败时可追溯 Lighthouse 报告;本地报告在.lighthouseci/,可用cat .lighthouseci/lhr-*.json查看详细 JSON。 - CI 检查分层:Astro Check(类型)、ESLint、Build 为阻断性 ✅ 检查;Lighthouse 为非阻断 ⚠️ 检查。这意味着性能回归不会自动拦截合并,需要人工关注告警或运行
performance-check.js。
Extension Points
- 新增被测页面:编辑
lighthouserc.json的url数组即可,无需改动其他环节:
1"url": [
2 "http://localhost:4321/",
3 "http://localhost:4321/about/",
4 "http://localhost:4321/anime/",
5 "http://localhost:4321/new-page/"
6]Source: docs/PERFORMANCE_MONITORING.md
- 调整阈值/断言级别:
assertions中按指标设置warn/off/error级别与数值阈值,可将性能检查从"警告"升级为"阻断"。 - 运行时指标扩展:
src/utils/performance-observer.ts是自定义指标收集的载体(仓库中确认存在该文件),可用于扩展 Web Vitals 之外的观测项;其内部实现未在本次核验中逐行阅读,扩展前请先阅读该文件。
Related Links
- docs/PERFORMANCE_MONITORING.md — 性能监控完整指南(本页主要信息源)
- src/utils/performance-observer.ts — 运行时 Performance Observer 工具
- README.en.md — 项目功能清单中提及 lazy loading 与 caching 性能优化
- 部署与流水线整体说明:见部署与运维(deployment-operations)相关兄弟页面