Comprehensive Performance Checklist

Use this checklist for auditing existing sites or ensuring new projects launch with optimal performance. Check items as you implement them.

A. Strategy & Measurement

Performance Culture

  • [ ] Performance goals are documented and shared with the full team
  • [ ] Representative test device chosen (mid-range Android, e.g. Samsung Galaxy A15)
  • [ ] Competitive performance benchmarking completed (target: 20% faster than fastest competitor)
  • [ ] Performance champion or rotating role assigned
  • [ ] Performance metrics included in sprint reviews and team dashboards

Core Web Vitals Targets

  • [ ] LCP ≀ 2.5s at P75 (field data)
  • [ ] INP ≀ 200ms at P75 (field data)
  • [ ] CLS ≀ 0.1 at P75 (field data)
  • [ ] TTFB ≀ 800ms at P75
  • [ ] FCP ≀ 1.8s at P75

Performance Budgets & Monitoring

  • [ ] JavaScript budget set (<200KB gzipped total)
  • [ ] CSS budget set (<50KB gzipped)
  • [ ] Image budget per page defined
  • [ ] Performance budgets enforced in CI/CD (Size-limit, Lighthouse CI, Bundlewatch)
  • [ ] Real User Monitoring (RUM) collecting Core Web Vitals in production
  • [ ] CrUX data monitored in Google Search Console
  • [ ] Synthetic monitoring (Lighthouse/WebPageTest) running on key pages on schedule
  • [ ] Alerting configured for metric regressions

B. JavaScript & Build Pipeline

Build Tools

  • [ ] Using a modern bundler (Vite 8, Rspack, Turbopack, or equivalent)
  • [ ] Linting with Oxlint or Biome (50–100Γ— faster than ESLint)
  • [ ] TypeScript type-checking optimized (tsgo or incremental builds)
  • [ ] Production builds use minification and compression

Code Splitting & Tree Shaking

  • [ ] Route-based code splitting implemented
  • [ ] Heavy components lazy-loaded with React.lazy() or dynamic import()
  • [ ] Barrel files eliminated or optimized (barrel-begone, direct imports)
  • [ ] sideEffects: false configured in package.json where safe
  • [ ] Dead code detection run (Knip) and unused exports removed
  • [ ] Bundle analyzer run to identify largest dependencies

JavaScript Execution

  • [ ] No synchronous third-party scripts in <head>
  • [ ] Long tasks broken up with scheduler.yield() or scheduler.postTask()
  • [ ] Heavy computation offloaded to Web Workers where appropriate
  • [ ] Speculation Rules or prefetch configured for likely next navigations
  • [ ] defer or type="module" used on all non-critical scripts

C. Rendering & Frameworks

Rendering Strategy

  • [ ] Appropriate rendering strategy chosen (SSR/SSG/ISR/Streaming/Islands) for the content type
  • [ ] Server-side rendering used for content-heavy pages
  • [ ] Static generation used for pages that change infrequently
  • [ ] Streaming SSR with Suspense boundaries for progressive loading

React Optimization (if applicable)

  • [ ] React Server Components used for non-interactive content
  • [ ] React Compiler enabled (eliminates manual memoization)
  • [ ] startTransition used for non-urgent state updates
  • [ ] Virtual lists used for long scrollable lists (TanStack Virtual)
  • [ ] Context providers split to minimize re-render blast radius
  • [ ] State management library chosen appropriately (Zustand/Jotai for most cases)
  • [ ] TanStack Query or SWR used for server state (caching, deduplication)

D. Assets & Loading

Images

  • [ ] AVIF served as primary format with WebP and JPEG fallbacks via <picture>
  • [ ] Responsive images implemented with srcset and sizes
  • [ ] LCP image has fetchpriority="high" and is NOT lazy-loaded
  • [ ] Below-fold images have loading="lazy" and decoding="async"
  • [ ] All <img> elements have explicit width and height attributes
  • [ ] LCP image preloaded in <head> (especially if CSS background-image or deep in DOM)
  • [ ] Images compressed with Squoosh, Sharp, or an image CDN
  • [ ] SVGs optimized with SVGO/SVGOMG
  • [ ] Animated GIFs replaced with <video autoplay loop muted playsinline> (AV1/H.264)

CSS

  • [ ] Critical CSS inlined in <head> (<14KB compressed)
  • [ ] Remaining CSS loaded asynchronously
  • [ ] content-visibility: auto applied to off-screen content sections
  • [ ] CSS @layer used for specificity management
  • [ ] Unused CSS removed (PurgeCSS, Coverage tab, or framework tree-shaking)
  • [ ] CSS Modules, vanilla-extract, or Tailwind used (zero-runtime)
  • [ ] No runtime CSS-in-JS (styled-components/Emotion) in new projects
  • [ ] Native CSS nesting used instead of Sass where possible

Modern CSS Replacing JavaScript

  • [ ] Container queries used instead of JS-based ResizeObserver for component responsiveness
  • [ ] :has() used for parent/sibling-based conditional styling instead of JS state
  • [ ] Scroll-driven animations used instead of GSAP/ScrollMagic where possible (with prefers-reduced-motion)
  • [ ] CSS anchor positioning evaluated for tooltips/popovers (replacing Floating UI)
  • [ ] Popover API used for show/hide overlays (replacing custom JS modal logic)
  • [ ] View Transitions API evaluated for page/state transitions
  • [ ] interpolate-size: allow-keywords added to CSS reset
  • [ ] @starting-style used for entry/exit animations from display: none

Fonts

  • [ ] WOFF2 format used exclusively (no TTF/OTF/EOT/SVG)
  • [ ] Fonts self-hosted (not loaded from Google Fonts CDN)
  • [ ] font-display: swap or optional set on all @font-face rules
  • [ ] Font metric overrides configured (size-adjust, ascent-override, descent-override) to minimize CLS
  • [ ] Fonts subsetted to required character ranges with unicode-range
  • [ ] Only necessary weights loaded (2–3 max; consider variable fonts for 3+)
  • [ ] Critical font preloaded with <link rel="preload" as="font" crossorigin>
  • [ ] Icon fonts replaced with SVG icons (Lucide, Heroicons, or inline SVG)
  • [ ] Font files cached with long max-age + immutable

Third-Party Scripts

  • [ ] All third-party scripts load with async or defer (none synchronous)
  • [ ] Facade pattern used for heavy embeds (YouTube, chat widgets, maps)
  • [ ] Third-party scripts loaded after user interaction or after page load where possible
  • [ ] Partytown evaluated for offloading remaining heavy third-party scripts to Web Workers
  • [ ] Consent mode configured (don’t load tracking before consent where legally required)
  • [ ] Tag manager audited quarterly; unused tags removed
  • [ ] Third-party JavaScript budget set and enforced (<100KB compressed)
  • [ ] Content Security Policy (CSP) configured to restrict script sources

Resource Hints

  • [ ] <link rel="preconnect"> added for 2–4 critical third-party origins
  • [ ] <link rel="dns-prefetch"> added for non-critical third-party domains
  • [ ] LCP image preloaded (with imagesrcset/imagesizes for responsive)
  • [ ] Critical font preloaded
  • [ ] modulepreload used for critical JS entry point modules
  • [ ] fetchpriority="high" on LCP element; fetchpriority="low" on non-critical images
  • [ ] Speculation Rules configured for likely next navigations
  • [ ] 103 Early Hints enabled at CDN level (if supported)
  • [ ] No over-preloading (limit to 1–3 truly critical resources)

E. Infrastructure & Networking

Network Protocols & Compression

  • [ ] HTTPS enforced with HSTS (consider HSTS preload)
  • [ ] TLS 1.3 enabled; TLS 1.0/1.1 disabled
  • [ ] HTTP/2 enabled (minimum)
  • [ ] HTTP/3 (QUIC) enabled at CDN or server level
  • [ ] Brotli compression enabled for text assets (CSS, JS, HTML, SVG, JSON)
  • [ ] Zstandard (zstd) compression evaluated for dynamic content
  • [ ] Images, WOFF2 fonts, and video NOT double-compressed via HTTP compression
  • [ ] TCP BBR congestion control enabled on Linux servers

CDN & Caching

  • [ ] CDN in use for all static assets
  • [ ] Fingerprinted assets cached with max-age=31536000, immutable
  • [ ] HTML/API responses use stale-while-revalidate for speed + freshness
  • [ ] Vary: Accept-Encoding set on compressed responses
  • [ ] s-maxage used for CDN-specific cache TTLs where appropriate
  • [ ] Edge functions used for latency-sensitive dynamic logic (auth, geo, A/B)
  • [ ] Service worker caching strategy implemented (Cache First for static, SWR for dynamic)
  • [ ] No caching of personalized/authenticated content in shared caches (private)

F. Quality, Security & DX

Testing & Debugging

  • [ ] Lighthouse CI configured in deployment pipeline with assertion thresholds
  • [ ] Bundle size budgets enforced in CI (Size-limit or Bundlewatch)
  • [ ] Performance regression = blocking PR check (not advisory)
  • [ ] WebPageTest used for deep waterfall analysis of key pages
  • [ ] Chrome DevTools Performance panel used for INP/LCP debugging
  • [ ] Coverage tab checked for unused CSS/JS

Security

  • [ ] HTTPS with HSTS and preload list submission
  • [ ] Content Security Policy deployed (even if Report-Only initially)
  • [ ] Subresource Integrity (SRI) on CDN-hosted scripts
  • [ ] Permissions Policy configured (disable unused features for iframes)
  • [ ] Dependencies audited (npm audit, Socket.dev)
  • [ ] No third-party polyfill CDNs (self-host or use Cloudflare alternative)

Accessibility + Performance

  • [ ] prefers-reduced-motion respected (all animations wrapped in media query)
  • [ ] prefers-reduced-transparency respected where applicable
  • [ ] Semantic HTML used (reducing need for JS-powered interactivity)
  • [ ] Popover API and <dialog> used instead of custom JS modals
  • [ ] Keyboard navigation works without JavaScript where possible

Developer Experience

  • [ ] Fast HMR/Fast Refresh configured (<100ms feedback loop)
  • [ ] Monorepo tooling (Turborepo/Nx) with remote caching if applicable
  • [ ] Performance tested on a real mid-range Android device, not just desktop
  • [ ] Team educated on performance impact of npm install decisions

This checklist is derived from the Modern Web Performance Guide 2026. Each item references the corresponding section for detailed implementation guidance. For the latest updates, check the individual resources linked throughout the guide.


Full Guide: All 22 Sections