mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-09-16 10:32:10 +00:00
perf: fix slow page loads and gate performance in CI
- Ship one hashed Tailwind stylesheet instead of two (one render-blocking) - Compress responses in-app (brotli/gzip, streaming-safe) and precompress the node build so local and CI measurements match production - Validate the Supabase session once per request - Render the homepage immediately and stream public stats - Stream a Pokedex's entries with the page instead of fetching after hydration, running the rows and count queries in parallel - Shrink the avatar and offline placeholder images, fix layout shift, contrast, link names and missing meta descriptions - Add Lighthouse CI (mobile + desktop) with score and metric budgets, bundle-size budgets in the build tests, and signed-in speed scenarios
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
// Lighthouse CI: `npm run test:lighthouse` builds the Node adapter output, serves it and audits the
|
||||
// public pages. Any category below 90 fails the run (and so the PR).
|
||||
// Set LHCI_PRESET=desktop to audit with the desktop profile; the default is Lighthouse's mobile
|
||||
// profile (slow 4G + CPU throttling), which is the stricter of the two.
|
||||
const preset = process.env.LHCI_PRESET === 'desktop' ? 'desktop' : undefined;
|
||||
|
||||
module.exports = {
|
||||
ci: {
|
||||
collect: {
|
||||
startServerCommand: 'npm run preview-node',
|
||||
startServerReadyPattern: 'Listening on',
|
||||
url: [
|
||||
'http://localhost:4173/',
|
||||
'http://localhost:4173/signin',
|
||||
'http://localhost:4173/welcome',
|
||||
'http://localhost:4173/offline-guide',
|
||||
'http://localhost:4173/forgot-password'
|
||||
],
|
||||
// Median of three runs smooths out noise from shared CI runners.
|
||||
numberOfRuns: 3,
|
||||
settings: {
|
||||
...(preset ? { preset } : {}),
|
||||
chromeFlags: '--no-sandbox --headless=new'
|
||||
}
|
||||
},
|
||||
assert: {
|
||||
assertions: {
|
||||
'categories:performance': ['error', { minScore: 0.9 }],
|
||||
'categories:accessibility': ['error', { minScore: 0.9 }],
|
||||
'categories:best-practices': ['error', { minScore: 0.9 }],
|
||||
'categories:seo': ['error', { minScore: 0.9 }],
|
||||
// The app compresses its own responses (see src/lib/server/compression.ts and the
|
||||
// precompressed build), so nothing may be served uncompressed.
|
||||
'uses-text-compression': ['error', { minScore: 1 }],
|
||||
// Regression budgets, set a little above what every audited page measured in September
|
||||
// 2026 (mobile profile: LCP 1.4-2.6 s, TBT 0 ms, CLS 0, ~100 KB script, ~14 KB CSS and
|
||||
// ~175 KB in total over the wire). A PR that makes pages meaningfully slower or heavier
|
||||
// fails here even while the category scores stay above 90. When a change legitimately
|
||||
// needs more, raise the number in the same PR so the cost is reviewed.
|
||||
'largest-contentful-paint': ['error', { maxNumericValue: 3000 }],
|
||||
'total-blocking-time': ['error', { maxNumericValue: 200 }],
|
||||
'cumulative-layout-shift': ['error', { maxNumericValue: 0.05 }],
|
||||
'resource-summary:script:size': ['error', { maxNumericValue: 115 * 1024 }],
|
||||
'resource-summary:stylesheet:size': ['error', { maxNumericValue: 20 * 1024 }],
|
||||
'resource-summary:total:size': ['error', { maxNumericValue: 220 * 1024 }]
|
||||
}
|
||||
},
|
||||
upload: {
|
||||
target: 'filesystem',
|
||||
outputDir: '.lighthouseci/reports'
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user