-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlighthouserc.js
More file actions
72 lines (68 loc) · 3.03 KB
/
Copy pathlighthouserc.js
File metadata and controls
72 lines (68 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Lighthouse CI lab gate. budgets.json is the single source of truth: only
// metrics with a calibrated (non-null) budget are enforced as errors; the rest
// stay as warnings until `pnpm perf:calibrate` fills them in (decision 10).
const budgets = require("./budgets.json");
const m = budgets.metrics;
const assertions = {
"categories:performance": ["warn", { minScore: 0.9 }],
// SEO is a hard gate at 100: the 8 SEO audits (indexability, canonical, meta
// description, title, crawlable anchors, descriptive link text, viewport,
// valid hreflang) all pass. Asserted from the same LH runs, so no extra CI
// time. A perfect SEO score is the floor for a site at this level of care.
"categories:seo": ["error", { minScore: 1 }],
};
function gate(key, auditId, severity = "error") {
if (m[key] && m[key].budget != null) {
assertions[auditId] = [severity, { maxNumericValue: m[key].budget, aggregationMethod: "median" }];
}
}
// LCP is advisory here, NOT a hard gate. Lighthouse measures simulated mobile
// Slow-4G (Lantern), which projects ~3.5s for this page even though the observed
// resource load is ~30ms and the real-world LCP is ~1s (load ~444ms). budgets.json
// documents Fast-4G, which lighthouse has no profile for, so the two never aligned.
// CLS and TBT stay hard errors; INP is hard-gated by e2e/perf.spec.ts. The LCP
// budget stays documented in budgets.json as the target.
gate("lcp", "largest-contentful-paint", "warn");
gate("cls", "cumulative-layout-shift");
gate("tbt", "total-blocking-time");
// Non-budget preset audits that are error-level under lighthouse:no-pwa but are
// not calibrated budgets and are not actionable here (same rationale as the
// insight audits below): unused-javascript fires on Next's own framework chunks
// (loaded for the app, not all executed on the first route) and can't reach 0.
const OPPORTUNITY_AUDITS_OFF = ["unused-javascript"];
for (const id of OPPORTUNITY_AUDITS_OFF) assertions[id] = "off";
// Lighthouse's experimental "insight" audits are strict, noisy, and often not
// actionable for a Next app (e.g. legacy-javascript fires on Next's own nomodule
// polyfills). Turn them off so the gate stays focused on the calibrated budgets.
const INSIGHT_AUDITS = [
"cls-culprits-insight",
"document-latency-insight",
"dom-size-insight",
"duplicated-javascript-insight",
"font-display-insight",
"forced-reflow-insight",
"image-delivery-insight",
"interaction-to-next-paint-insight",
"lcp-discovery-insight",
"lcp-breakdown-insight",
"legacy-javascript-insight",
"modern-http-insight",
"network-dependency-tree-insight",
"render-blocking-insight",
"slow-css-selector-insight",
"third-parties-insight",
"viewport-insight",
"cache-insight",
];
for (const id of INSIGHT_AUDITS) assertions[id] = "off";
module.exports = {
ci: {
collect: {
numberOfRuns: budgets.measurement.runs || 5,
startServerCommand: "pnpm start",
url: [budgets.url],
},
assert: { preset: "lighthouse:no-pwa", assertions },
upload: { target: "temporary-public-storage" },
},
};