Use this as a pre-deploy checklist to keep bundles small and fast π
- JavaScript
- CSS
- Images
- Fonts
- HTML
- Compression
- Caching
- Network
- Build & Tooling
- React-Specific Optimizations
- Third-Party Scripts
- Common Mistakes
- Performance Budgets
- Quick Reference
- [ ] Production build enabled
- [ ] Tree-shaking working (ES modules)
- [ ] Code splitting with
import() - [ ] Remove unused exports
- [ ] Avoid heavy libraries
- [ ] Use per-method imports (lodash, date-fns)
- [ ] Minify & mangle code
- [ ] Drop
console.login prod - [ ] Avoid polyfills you don't need
- [ ] Analyze bundle size
- [ ] Use dynamic imports for routes
- [ ] Implement vendor chunking
- [ ] Remove duplicate dependencies
- [ ] Use smaller alternatives (date-fns vs moment)
- [ ] Defer non-critical JavaScript
- [ ] Avoid inline scripts in HTML
- [ ] Minify CSS
- [ ] Remove unused CSS (PurgeCSS)
- [ ] Avoid large CSS frameworks if unused
- [ ] Split critical vs non-critical CSS
- [ ] Inline critical CSS
- [ ] Avoid duplicate styles
- [ ] Prefer utility-first CSS (Tailwind)
- [ ] Avoid deep selectors
- [ ] Extract CSS to separate files
- [ ] Use CSS modules or scoped styles
- [ ] Remove unused
@keyframes - [ ] Avoid
@importin CSS - [ ] Optimize CSS specificity
- [ ] Use shorthand properties
- [ ] Remove vendor prefixes for modern browsers
- [ ] Convert to
.webp/.avif - [ ] Compress images
- [ ] Use responsive images (
srcset) - [ ] Lazy load off-screen images
- [ ] Avoid oversized images
- [ ] Use SVG for icons
- [ ] Blur / skeleton placeholders
- [ ] CDN for image delivery
- [ ] Optimize image dimensions
- [ ] Use
<picture>for art direction - [ ] Add
widthandheightattributes - [ ] Use progressive JPEG
- [ ] Implement LQIP (Low Quality Image Placeholder)
- [ ] Add
loading="lazy"attribute - [ ] Use
decoding="async"for non-critical images - [ ] Sprite sheets for small icons
- [ ] Remove image metadata (EXIF)
- [ ] Use
.woff2 - [ ] Limit font variants
- [ ] Preload critical fonts
- [ ] Use
font-display: swap - [ ] Subset fonts
- [ ] Avoid multiple font families
- [ ] Self-host fonts instead of Google Fonts
- [ ] Use system fonts when appropriate
- [ ] Use variable fonts to reduce variants
- [ ] Remove unused font weights/styles
- [ ] Avoid FOIT (Flash of Invisible Text)
- [ ] Use
unicode-rangefor subsetting - [ ] Preconnect to font CDNs
- [ ] Minify HTML
- [ ] Remove unused meta/scripts
- [ ] Inline critical CSS
- [ ] Defer non-critical scripts
- [ ] Avoid inline JS where possible
- [ ] Use semantic HTML
- [ ] Remove HTML comments in production
- [ ] Optimize DOM depth
- [ ] Use
asyncfor independent scripts - [ ] Add
deferto non-critical scripts - [ ] Remove unnecessary attributes
- [ ] Enable Brotli
- [ ] Fallback to Gzip
- [ ] Compress JS, CSS, HTML, JSON, SVG
- [ ] Configure compression level (6-9 for Brotli)
- [ ] Pre-compress static assets at build time
- [ ] Verify compression headers
- [ ] Compress API responses
- [ ] Use streaming compression for large files
- [ ] Hash filenames (
app.3fd2.js) - [ ] Long-term cache static assets
- [ ] Use
Cache-Control: immutable - [ ] Avoid caching HTML aggressively
- [ ] CDN caching enabled
- [ ] Set appropriate
max-agevalues - [ ] Use service workers for offline caching
- [ ] Implement stale-while-revalidate
- [ ] Version API responses when cacheable
- [ ] Configure ETags properly
- [ ] Use content-based hashing
- [ ] Invalidate cache on deployment
- [ ] Reduce number of requests
- [ ] Bundle small assets
- [ ] HTTP/2 or HTTP/3 enabled
- [ ] Avoid large request headers
- [ ] Use CDN for static files
- [ ] Enable keep-alive connections
- [ ] Minimize DNS lookups
- [ ] Use
rel="preconnect"for critical origins - [ ] Avoid redirect chains
- [ ] Implement resource hints (
dns-prefetch,prefetch) - [ ] Use connection pooling
- [ ] Optimize TTFB (Time to First Byte)
- [ ] Production mode enabled
- [ ] Source maps hidden or limited
- [ ] Bundle analyzer used
- [ ] Dead code eliminated
- [ ] Environment-specific configs
- [ ] Use modern bundlers (Vite, esbuild, SWC)
- [ ] Configure proper module resolution
- [ ] Enable terser/uglify for minification
- [ ] Use differential serving (modern/legacy)
- [ ] Automate optimization in CI/CD
- [ ] Set up performance budgets
- [ ] Monitor bundle size over time
- [ ] Use import maps for dependencies
- [ ] Configure proper polyfills
- [ ] Use production build (
NODE_ENV=production) - [ ] Implement code splitting with
React.lazy() - [ ] Use
Suspensefor lazy components - [ ] Memoize components with
React.memo - [ ] Use
useMemofor expensive computations - [ ] Use
useCallbackfor function props - [ ] Implement virtual scrolling for long lists
- [ ] Avoid unnecessary re-renders
- [ ] Use keys properly in lists
- [ ] Optimize context usage
- [ ] Use
Fragmentinstead of div wrappers - [ ] Implement route-based code splitting
- [ ] Avoid inline function definitions in JSX
- [ ] Use production builds of dependencies
- [ ] Profile with React DevTools
- [ ] Implement progressive hydration
- [ ] Use server-side rendering (SSR) or static generation (SSG)
- [ ] Optimize bundle with tree-shaking friendly imports
- [ ] Load analytics asynchronously
- [ ] Defer non-critical third-party scripts
- [ ] Use
asyncfor independent scripts - [ ] Self-host third-party libraries when possible
- [ ] Remove unused third-party scripts
- [ ] Minimize number of third-party dependencies
- [ ] Use facade pattern for heavy embeds (YouTube, maps)
- [ ] Implement consent management for privacy
- [ ] Monitor third-party script performance
- [ ] Use SRI (Subresource Integrity) for CDN scripts
- β Shipping dev builds
- β Importing full libraries (
import _ from 'lodash') - β Large background images
- β Multiple font families
- β No caching headers
- β Not using compression
- β Loading all routes upfront
- β Inline styles in production
- β Missing
width/heighton images - β Not lazy-loading images
- β Using heavy UI libraries unnecessarily
- β Not analyzing bundle size
- β Ignoring Core Web Vitals
- β Shipping source maps to production
- β Not optimizing third-party scripts
- β Forgetting to enable HTTP/2
| Asset Type | Target | Max |
|---|---|---|
| JavaScript | < 150KB | < 300KB |
| CSS | < 50KB | < 100KB |
| Fonts | < 100KB | < 200KB |
| Images (per page) | Adaptive | < 1MB |
| Total Page Weight | < 500KB | < 1MB |
| Metric | Good | Needs Improvement | Poor |
|---|---|---|---|
| LCP | β€ 2.5s | 2.5s - 4.0s | > 4.0s |
| FID / INP | β€ 100ms / β€ 200ms | 100-300ms / 200-500ms | > 300ms / > 500ms |
| CLS | β€ 0.1 | 0.1 - 0.25 | > 0.25 |
| TTFB | β€ 800ms | 800ms - 1.8s | > 1.8s |
- JS: < 150KB (gzipped)
- CSS: < 50KB (gzipped)
- Images: Adaptive & lazy-loaded
- Fonts: Minimal variants, subset, woff2
Build & Analysis:
- webpack-bundle-analyzer
- source-map-explorer
- Bundlephobia
- Import Cost (VSCode extension)
Image Optimization:
- Squoosh
- ImageOptim
- Sharp
- SVGO
Performance Testing:
- Lighthouse
- WebPageTest
- Chrome DevTools
- React DevTools Profiler
Monitoring:
- Google PageSpeed Insights
- Vercel Analytics
- Web Vitals library
- Sentry Performance
Run these before every deployment:
- β Bundle analysis completed
- β Lighthouse score > 90
- β All images optimized
- β Production build verified
- β Compression enabled
- β Caching headers set
- β No console errors
- β Performance budgets met
# Analyze bundle size
npm run build -- --analyze
# Check bundle size
npx bundlephobia <package-name>
# Test compression
curl -H "Accept-Encoding: br,gzip" -I https://yoursite.com
# Lighthouse CI
npx lighthouse https://yoursite.com --view
# Check image sizes
du -sh public/images/*
# Find large files
find dist -type f -size +100k -exec ls -lh {} \;- Measure β Run Lighthouse & bundle analyzer
- Identify β Find largest assets and bottlenecks
- Optimize β Apply relevant checklist items
- Test β Verify improvements
- Monitor β Track metrics over time
- Repeat β Continuous optimization
- [ ] Implement partial hydration (Islands Architecture)
- [ ] Use Edge SSR for faster response times
- [ ] Implement streaming SSR
- [ ] Use module federation for micro-frontends
- [ ] Implement 103 Early Hints
- [ ] Use priority hints for critical resources
- [ ] Implement adaptive loading based on network
- [ ] Use import maps for better dependency management
- [ ] Implement progressive enhancement
- [ ] Use Web Workers for heavy computation
- [ ] Implement request deduplication
- [ ] Use GraphQL for optimized data fetching