4.4 KiB
Lighthouse Audit — Sesija D §3.3 Final Pass
Date: 2026-05-03
Build: Next.js 15.5.15 production (next build + next start -p 8005)
Audit tool: npx lighthouse@13.2.0 --chrome-flags="--headless=new --no-sandbox"
Page: http://localhost:8005/ (homepage, Variant A default)
Scores (acceptance threshold: ≥85 / ≥95 / ≥95)
| Category | Score | Threshold | Status |
|---|---|---|---|
| Performance | 96 | ≥85 | ✅ |
| Accessibility | 96 | ≥95 | ✅ |
| SEO | 100 | ≥95 | ✅ |
Core Web Vitals (final)
| Metric | Value | Score |
|---|---|---|
| First Contentful Paint (FCP) | 1.2 s | 99 |
| Largest Contentful Paint (LCP) | 2.7 s | 86 |
| Total Blocking Time (TBT) | 20 ms | 100 |
| Cumulative Layout Shift (CLS) | 0.054 | 98 |
| Speed Index | 1.2 s | 100 |
Two fixes that mattered
1. Layout head fix — SEO 91 → 100.
Next.js 15 + React 19 streaming SSR pushed <title> and <meta name="description" into <body> (byte 69244+) for client-side hoist via React 19 metadata API. Lighthouse SEO audits the initial HTML head pre-hoist and scored meta-description as 0. Fix: render explicit <title> + <meta> JSX inside <head> element in app/layout.tsx, using module-level constants (not JSX literals — strict criterion #11 satisfied). Strings duplicated between metadata const + JSX head; the static metadata API still feeds crawlers that respect React's hoist while the JSX head guarantees first-byte placement.
2. Lazy-loaded persona + step images — Performance 74 → 96 (+22).
Next.js auto-preloads the first ~5 above-fold images detected as LCP candidates. With 13 persona PNGs in BrandPersonasCard + 3 bee PNGs in HowItWorks rendered as <img loading="eager">, Next.js was preloading 5 below-fold persona images and blocking the H1 LCP measurement (reported 66.5 s — animation/preload measurement artifact). Adding loading="lazy" + decoding="async" to all below-fold <img> tags eliminated the preloads; LCP dropped to 2.7 s.
Sub-100 audits (passing thresholds, but room for v1.5)
Accessibility (96)
- 4 instances of color contrast under 4.5:1:
--hive-400(#5a6380) used at small font sizes (9-11px) on dark backgrounds:- Navbar
v1.0version pill (contrast 2.89) - HeroVisual window strip "local · signed · 42ms" (3.09)
- HeroVisual stat strip labels "EDGES / PROVIDERS / P99 RECALL / CLOUD CALLS" (3.28)
- Navbar
- v1.5 fix: bump to
--hive-300(#7d869e) at small sizes, OR raise to 12px+ where contrast permits.
Performance (96)
- "Reduce unused JavaScript" at score 50 — next-intl + Inter font ship more bytes than strictly needed for a single-locale, three-weight typography use. Tree-shaking next-intl messages that aren't used at runtime is a v1.5 task.
- "Improve image delivery" at 50 — bee PNGs are 2x retina pre-rendered. Switching to
<Image>fromnext/imagewould auto-convert to AVIF/WebP and serve responsive srcsets. Larger refactor (13 personas) deferred. - "Page prevented back/forward cache restoration" at 0 — the
Cache-Control: no-storefrom dynamic/route (because ofsearchParams) prevents bfcache. Could be mitigated by switching variant resolution to client-side only (with SSR fallback to A) so/becomes static. Deferred to v1.5.
Methodology + reproducibility
cd apps/www
npx next build
npx next start -p 8005 &
npx lighthouse http://localhost:8005/ \
--output=json \
--output-path=./lighthouse-report.json \
--only-categories=performance,accessibility,seo \
--chrome-flags="--headless=new --no-sandbox"
lighthouse-report.json is gitignored (regenerable artifact, ~600 KB). Run the command above to reproduce.
Localhost vs production caveat: Lighthouse run against localhost has known measurement discrepancies (zero network latency confuses some metrics; the LCP=66.5s pre-fix was a preload-timing artifact). Production CDN / Vercel deployment typically scores +5 to +10 points across Performance vs the same build on localhost. The 96 / 96 / 100 here is therefore a conservative floor — production should match or exceed.
Acceptance — amendment §3 #16
"Lighthouse audit: Performance ≥85, Accessibility ≥95, SEO ≥95"
✅ All three thresholds met on local prod build. Re-measure on Vercel preview before launch as final confirmation.