- Asset Optimization
- Loading Strategy
- HTTP & Transport
- Caching Strategy
- Images & Media
- JavaScript Performance
- API & Data Fetching
- Monitoring & Measurement
- Mobile & Low-Network Users
- Dev & Build Setup
- Bonus (Advanced)
- Additional Optimizations
- [ ] Minify JS, CSS, HTML
- [ ] Use Brotli (preferred) or Gzip compression
- [ ] Remove unused CSS (PurgeCSS)
- [ ] Tree-shake unused JS exports
- [ ] Split bundles (code splitting)
- [ ] Use modern formats:
.webp,.avif - [ ] Use SVG instead of PNG/JPG when possible
- [ ] Remove duplicate dependencies
- [ ] Use CSS sprites for small icons
- [ ] Inline small critical assets (< 4KB)
- [ ] Use
deferfor non-critical scripts - [ ] Use
asyncfor independent scripts - [ ] Lazy-load images (
loading="lazy") - [ ] Lazy-load routes/components
- [ ] Avoid render-blocking resources
- [ ] Inline critical CSS
- [ ] Load third-party scripts asynchronously
- [ ] Use
rel="preconnect"for critical origins - [ ] Implement resource hints (
dns-prefetch,preconnect) - [ ] Defer non-critical CSS loading
- [ ] Use HTTP/2 or HTTP/3
- [ ] Reduce number of requests
- [ ] Enable keep-alive
- [ ] Avoid large request headers
- [ ] Use CDN for static assets
- [ ] Enable QUIC protocol where supported
- [ ] Optimize connection pooling
- [ ] Reduce redirect chains
- [ ] Use domain sharding strategically (HTTP/1.1 only)
- [ ] Minimize DNS lookups
- [ ] Set proper
Cache-Controlheaders - [ ] Use immutable assets with hash-based filenames
- [ ] Cache API responses when safe
- [ ] Use Service Workers for offline + caching
- [ ] Implement stale-while-revalidate
- [ ] Configure ETags appropriately
- [ ] Use browser caching for static resources
- [ ] Implement memory caching for frequent data
- [ ] Cache DNS responses
- [ ] Use localStorage/sessionStorage wisely
- [ ] Serve responsive images (
srcset,sizes) - [ ] Compress images aggressively
- [ ] Avoid autoplay videos
- [ ] Stream large media instead of full download
- [ ] Use placeholders / blur-up technique
- [ ] Implement progressive JPEG loading
- [ ] Use
<picture>element for art direction - [ ] Lazy-load offscreen images
- [ ] Optimize image dimensions (don't serve oversized)
- [ ] Consider LQIP (Low Quality Image Placeholder)
- [ ] Use adaptive bitrate streaming for video
- [ ] Add
decoding="async"to images
- [ ] Avoid large libraries when smaller alternatives exist
- [ ] Prefer dynamic imports
- [ ] Debounce/throttle network calls
- [ ] Batch API requests
- [ ] Cancel unnecessary fetches (AbortController)
- [ ] Use Web Workers for heavy computation
- [ ] Avoid blocking the main thread
- [ ] Optimize third-party script loading
- [ ] Remove console.log in production
- [ ] Use requestAnimationFrame for animations
- [ ] Avoid memory leaks (remove event listeners)
- [ ] Use intersection observer instead of scroll events
- [ ] Reduce payload size (send only needed fields)
- [ ] Use pagination / infinite scrolling
- [ ] Use GraphQL fragments or REST filtering
- [ ] Compress JSON responses
- [ ] Implement client-side caching (SWR / React Query)
- [ ] Use HTTP/2 server push for critical resources
- [ ] Implement request deduplication
- [ ] Use WebSocket for real-time data instead of polling
- [ ] Batch multiple API calls into one
- [ ] Implement optimistic UI updates
- [ ] Use delta updates instead of full payloads
- [ ] Implement proper rate limiting
- [ ] Measure TTFB, LCP, CLS, FID
- [ ] Use Lighthouse regularly
- [ ] Monitor slow network scenarios (3G/4G)
- [ ] Log failed or slow requests
- [ ] Track real-user metrics (RUM)
- [ ] Monitor Core Web Vitals
- [ ] Set up performance budgets
- [ ] Use performance profiling tools
- [ ] Track bundle size over time
- [ ] Monitor error rates and timeouts
- [ ] Use synthetic monitoring
- [ ] Measure INP (Interaction to Next Paint)
- [ ] Optimize for slow connections
- [ ] Avoid heavy animations on load
- [ ] Reduce JavaScript execution time
- [ ] Provide offline fallback UI
- [ ] Implement adaptive loading based on connection
- [ ] Use Network Information API
- [ ] Reduce battery consumption
- [ ] Test on real mobile devices
- [ ] Optimize for touch interactions
- [ ] Reduce data usage with save-data header
- [ ] Enable production builds
- [ ] Analyze bundle size (
webpack-bundle-analyzer) - [ ] Use environment-based configs
- [ ] Avoid shipping source maps publicly
- [ ] Set correct MIME types
- [ ] Use modern build tools (Vite, esbuild)
- [ ] Enable tree-shaking in bundler
- [ ] Configure proper polyfills
- [ ] Use differential serving (modern/legacy bundles)
- [ ] Automate performance testing in CI/CD
- [ ] Prefetch important routes
- [ ] Preload critical assets
- [ ] Use edge caching
- [ ] Use partial hydration / islands
- [ ] Implement priority hints
- [ ] Use 103 Early Hints
- [ ] Implement streaming SSR
- [ ] Use module preloading
- [ ] Implement route-based code splitting
- [ ] Use import maps for dependencies
- [ ] Optimize font loading (font-display, preload)
- [ ] Implement progressive enhancement
- [ ] Use SRI (Subresource Integrity) for CDN assets
- [ ] Implement CSP (Content Security Policy)
- [ ] Use HSTS for secure connections
- [ ] Minimize third-party dependencies
- [ ] Use system fonts when appropriate
- [ ] Subset fonts to required characters
- [ ] Use variable fonts to reduce variants
- [ ] Implement
font-display: swaporoptional - [ ] Preload critical fonts
- [ ] Self-host fonts instead of Google Fonts
- [ ] Avoid @import in CSS
- [ ] Minimize CSS specificity
- [ ] Use CSS containment
- [ ] Optimize CSS animations (use transform/opacity)
- [ ] Remove unused keyframes
- [ ] Optimize database queries
- [ ] Use database connection pooling
- [ ] Implement database indexes
- [ ] Use Redis/Memcached for caching
- [ ] Enable database query caching
- [ ] Optimize N+1 queries
- [ ] Use client-side validation first
- [ ] Debounce form input validation
- [ ] Implement incremental validation
- [ ] Cache form state locally
- [ ] Load analytics scripts asynchronously
- [ ] Use server-side analytics when possible
- [ ] Batch analytics events
- [ ] Consider privacy-focused analytics (Plausible, Fathom)
- [ ] Use React.memo / useMemo / useCallback
- [ ] Implement virtual scrolling for long lists
- [ ] Use Suspense for data fetching
- [ ] Optimize re-renders
- [ ] Use production builds of frameworks
| Metric | Good | Needs Improvement | Poor |
|---|---|---|---|
| LCP | β€ 2.5s | 2.5s - 4.0s | > 4.0s |
| FID | β€ 100ms | 100ms - 300ms | > 300ms |
| CLS | β€ 0.1 | 0.1 - 0.25 | > 0.25 |
| TTFB | β€ 800ms | 800ms - 1.8s | > 1.8s |
| INP | β€ 200ms | 200ms - 500ms | > 500ms |
- Performance Testing: Lighthouse, WebPageTest, Chrome DevTools
- Bundle Analysis: webpack-bundle-analyzer, source-map-explorer
- Image Optimization: Squoosh, ImageOptim, Sharp
- Monitoring: Sentry, New Relic, Datadog, Vercel Analytics
- CDN: Cloudflare, Fastly, AWS CloudFront
- Compression: Brotli, Gzip, Zstandard
Start here for immediate impact:
- Enable compression (Brotli/Gzip)
- Optimize and compress images
- Minify CSS/JS
- Enable browser caching
- Use a CDN
- Lazy-load images
- Remove unused CSS/JS
- Use
deferon scripts