Skip to content

Performance

Outcome: a PWA that meets the Core Web Vitals thresholds and feels instant — fast to launch, responsive to input, visually stable. Performance work is a loop: measure, fix the biggest offender, measure again. Don’t optimise by guesswork.

The metrics, thresholds, and what each one captures are described in the Core Web Vitals reference; this guide is the procedure for moving them.

Metric What it measures Good
LCP Loading — largest element painted ≤ 2.5s
INP Responsiveness — input to next paint ≤ 200ms
CLS Visual stability — unexpected layout shift ≤ 0.1
  1. Measure first, on real conditions. Run Lighthouse and capture field data (Web Vitals) on a mid-tier device and throttled network. Optimising before measuring wastes effort on the wrong thing. Definitions are in the Core Web Vitals reference.

  2. Fix LCP — the largest paint. Preload the hero image/font, serve right-sized modern formats, and remove render-blocking resources so the main content paints sooner.

  3. Fix INP — input responsiveness. Break up long tasks, yield to the main thread, and defer non-critical JavaScript so taps and clicks respond within the budget.

  4. Fix CLS — layout stability. Reserve space for images, embeds, and late-loading content with explicit dimensions so nothing jumps as the page settles.

  5. Use the service worker for perceived speed. A cached app shell makes repeat launches feel instant — the PWA’s structural advantage over a plain site. The caching model is in the service worker reference.

  6. Re-measure and lock it in. Confirm the change moved the metric, then add a budget (Lighthouse CI or a Web Vitals check) so a regression is caught before it ships.

The numbers matter, but so does feel. Skeleton screens, optimistic UI, and an instant-launching cached shell make an app feel fast even when a network request is still in flight — and a fast-feeling app keeps users where a technically-fast-but-janky one loses them.

← Back to the Guides overview.