IR

← Case studies

Hitting Core Web Vitals on a content-heavy product

Pushing an Angular application from inconsistent CWV scores to passing the field thresholds on every monitored route.

Context

A content-heavy product where Largest Contentful Paint and Interaction to Next Paint were failing on real-user metrics, despite a respectable lab Lighthouse score. The gap between lab and field meant the issue was in real network and device conditions, not idealised builds.

Constraints

Couldn't drop the analytics or third-party scripts business needed. Couldn't fork to a different framework. Existing CDN setup had to keep working. Performance budget had to be enforceable, not aspirational.

Decisions

Shift focus from Lighthouse to field RUM. Treat CWV as a budget, not a goal. Address the dominant LCP element first (above-the-fold image), then route-level JS, then third-party scripts. Build a CI check that fails when bundle size or known LCP element regresses.

Implementation

Above-the-fold images served as AVIF with explicit dimensions and `fetchpriority=high`. Route-level code splitting with `loadComponent` + targeted prefetch on intent. Third-party scripts moved behind interaction or visibility triggers. Bundle budget gating in CI.

Outcome

LCP and INP moved into the green band on real-user data. Performance stopped being a recurring fire and became a property guarded by CI. The team gained a vocabulary for tradeoffs ("this costs us 30 KB on the LCP route").

Outcome metrics

Performance
LCP/INP green on field data
Maintainability
Performance guarded by automated checks
Bundle size
Per-route budgets enforced in CI