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 dynamicimport() - [ ] Barrel files eliminated or optimized (barrel-begone, direct imports)
- [ ]
sideEffects: falseconfigured inpackage.jsonwhere 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()orscheduler.postTask() - [ ] Heavy computation offloaded to Web Workers where appropriate
- [ ] Speculation Rules or
prefetchconfigured for likely next navigations - [ ]
deferortype="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)
- [ ]
startTransitionused 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
srcsetandsizes - [ ] LCP image has
fetchpriority="high"and is NOT lazy-loaded - [ ] Below-fold images have
loading="lazy"anddecoding="async" - [ ] All
<img>elements have explicitwidthandheightattributes - [ ] 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: autoapplied to off-screen content sections - [ ] CSS
@layerused 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
ResizeObserverfor 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-keywordsadded to CSS reset - [ ]
@starting-styleused for entry/exit animations fromdisplay: none
Fonts
- [ ] WOFF2 format used exclusively (no TTF/OTF/EOT/SVG)
- [ ] Fonts self-hosted (not loaded from Google Fonts CDN)
- [ ]
font-display: swaporoptionalset on all@font-facerules - [ ] 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
asyncordefer(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/imagesizesfor responsive) - [ ] Critical font preloaded
- [ ]
modulepreloadused 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-revalidatefor speed + freshness - [ ]
Vary: Accept-Encodingset on compressed responses - [ ]
s-maxageused 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-motionrespected (all animations wrapped in media query) - [ ]
prefers-reduced-transparencyrespected 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 installdecisions
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.