--- name: web-performance-optimization description: Comprehensive guide to web performance optimization techniques, Core Web Vitals, and best practices across frameworks --- # Web Performance Optimization Guide This skill provides comprehensive knowledge about web performance optimization, Core Web Vitals, and practical techniques for improving website speed and user experience. ## Core Web Vitals ### 1. Largest Contentful Paint (LCP) **What it measures:** Loading performance - time until the largest content element is visible. **Good:** < 2.5s | **Needs Improvement:** 2.5s - 4.0s | **Poor:** > 4.0s **Common causes of poor LCP:** - Slow server response times - Render-blocking JavaScript and CSS - Slow resource load times - Client-side rendering **Optimization strategies:** ```html Hero Description ``` ```javascript // Implement adaptive loading based on network if (navigator.connection && navigator.connection.effectiveType === '4g') { // Load high-res images } else { // Load lower-res images } ``` ### 2. First Input Delay (FID) / Interaction to Next Paint (INP) **What it measures:** Interactivity - time from first user interaction to browser response. **Good (FID):** < 100ms | **Needs Improvement:** 100ms - 300ms | **Poor:** > 300ms **Good (INP):** < 200ms | **Needs Improvement:** 200ms - 500ms | **Poor:** > 500ms **Common causes:** - Heavy JavaScript execution - Long tasks blocking main thread - Large bundle sizes **Optimization strategies:** ```javascript // Code splitting - load only what's needed import('./heavy-module.js').then(module => { module.init(); }); // Use web workers for heavy computation const worker = new Worker('worker.js'); worker.postMessage({data: largeDataset}); // Debounce expensive operations const debouncedSearch = debounce((query) => { performSearch(query); }, 300); // Use requestIdleCallback for non-critical work requestIdleCallback(() => { analytics.track('page_view'); }); ``` ### 3. Cumulative Layout Shift (CLS) **What it measures:** Visual stability - unexpected layout shifts during page load. **Good:** < 0.1 | **Needs Improvement:** 0.1 - 0.25 | **Poor:** > 0.25 **Common causes:** - Images without dimensions - Dynamically injected content - Web fonts causing FOIT/FOUT - Ads, embeds, iframes **Optimization strategies:** ```html Description
``` ## Performance Optimization Techniques ### 1. Resource Optimization #### Image Optimization ```bash # Convert to WebP (90% smaller than JPEG) cwebp input.jpg -q 80 -o output.webp # Generate responsive images convert input.jpg -resize 400x output-400w.jpg convert input.jpg -resize 800x output-800w.jpg convert input.jpg -resize 1200x output-1200w.jpg ``` ```html Description ``` #### JavaScript Optimization ```javascript // Tree shaking - import only what you need import { debounce } from 'lodash-es'; // Good // import _ from 'lodash'; // Bad - imports everything // Dynamic imports for route-based code splitting const Home = lazy(() => import('./pages/Home')); const About = lazy(() => import('./pages/About')); // Minimize third-party scripts // Use Partytown for offloading to web worker ``` #### CSS Optimization ```html ``` ### 2. Network Optimization #### Compression ```nginx # Enable gzip/brotli compression (nginx) gzip on; gzip_types text/plain text/css application/json application/javascript; gzip_min_length 1000; # Brotli (better compression) brotli on; brotli_types text/plain text/css application/json application/javascript; ``` #### HTTP/2 & HTTP/3 ```nginx # Enable HTTP/2 listen 443 ssl http2; # Enable HTTP/3 (QUIC) listen 443 quic reuseport; add_header Alt-Svc 'h3=":443"; ma=86400'; ``` #### Caching Strategy ```javascript // Service Worker caching self.addEventListener('install', (event) => { event.waitUntil( caches.open('v1').then((cache) => { return cache.addAll([ '/', '/styles.css', '/script.js', '/logo.svg' ]); }) ); }); // Cache-first strategy for static assets self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((response) => { return response || fetch(event.request); }) ); }); ``` ```nginx # HTTP caching headers location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 1y; add_header Cache-Control "public, immutable"; } ``` ### 3. Rendering Optimization #### Critical Rendering Path ```html ``` #### Server-Side Rendering (SSR) vs Client-Side Rendering (CSR) ```javascript // Next.js - Hybrid approach export async function getServerSideProps() { // Fetch data on server const data = await fetch('https://api.example.com/data'); return { props: { data } }; } // Static generation for faster TTFB export async function getStaticProps() { const data = await fetch('https://api.example.com/data'); return { props: { data }, revalidate: 60 // ISR - revalidate every 60s }; } ``` ### 4. Framework-Specific Optimizations #### React ```javascript // Lazy load components const HeavyComponent = lazy(() => import('./HeavyComponent')); // Memoization const MemoizedComponent = React.memo(({ data }) => { return
{data}
; }); // useMemo for expensive computations const expensiveValue = useMemo(() => { return computeExpensiveValue(a, b); }, [a, b]); // useCallback for function references const handleClick = useCallback(() => { doSomething(a); }, [a]); // Virtualization for long lists import { FixedSizeList } from 'react-window'; {Row} ``` #### Vue ```javascript // Async components const AsyncComponent = defineAsyncComponent(() => import('./HeavyComponent.vue') ); // Keep-alive for component caching // v-once for static content
{{ staticContent }}
// Virtual scrolling import { RecycleScroller } from 'vue-virtual-scroller'; ``` #### Angular ```typescript // Lazy loading routes const routes: Routes = [ { path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) } ]; // OnPush change detection @Component({ selector: 'app-component', changeDetection: ChangeDetectionStrategy.OnPush }) // TrackBy for *ngFor
{{ item.name }}
trackByFn(index, item) { return item.id; } ``` ## Database & Backend Optimization ### N+1 Query Problem ```javascript // Bad - N+1 queries const users = await User.findAll(); for (const user of users) { const posts = await Post.findAll({ where: { userId: user.id } }); } // Good - Single query with join const users = await User.findAll({ include: [{ model: Post }] }); ``` ### Caching Strategies ```javascript // Redis caching const cached = await redis.get(`user:${id}`); if (cached) { return JSON.parse(cached); } const user = await db.users.findById(id); await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 3600); return user; // Memoization const memoize = (fn) => { const cache = new Map(); return (...args) => { const key = JSON.stringify(args); if (cache.has(key)) return cache.get(key); const result = fn(...args); cache.set(key, result); return result; }; }; ``` ### Database Indexing ```sql -- Create indexes for frequently queried columns CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_posts_user_id ON posts(user_id); -- Composite indexes for multi-column queries CREATE INDEX idx_posts_user_date ON posts(user_id, created_at); -- Analyze query performance EXPLAIN ANALYZE SELECT * FROM posts WHERE user_id = 123; ``` ## Performance Monitoring ### Real User Monitoring (RUM) ```javascript // Web Vitals API import {getCLS, getFID, getFCP, getLCP, getTTFB} from 'web-vitals'; getCLS(console.log); getFID(console.log); getFCP(console.log); getLCP(console.log); getTTFB(console.log); // Send to analytics function sendToAnalytics({name, value, id}) { analytics.track('web-vital', { metric: name, value: Math.round(value), id }); } getCLS(sendToAnalytics); getLCP(sendToAnalytics); ``` ### Performance Observer API ```javascript // Observe long tasks const observer = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { if (entry.duration > 50) { console.warn('Long task detected:', entry); } } }); observer.observe({entryTypes: ['longtask']}); // Monitor resource timing new PerformanceObserver((list) => { for (const entry of list.getEntries()) { console.log('Resource:', entry.name, 'Duration:', entry.duration); } }).observe({entryTypes: ['resource']}); ``` ## Common Performance Anti-Patterns ### 1. Blocking the Main Thread ```javascript // Bad - blocks UI for (let i = 0; i < 1000000; i++) { // Heavy computation } // Good - chunk work function processInChunks(data, chunkSize = 100) { let index = 0; function processChunk() { const chunk = data.slice(index, index + chunkSize); // Process chunk index += chunkSize; if (index < data.length) { requestIdleCallback(processChunk); } } processChunk(); } ``` ### 2. Memory Leaks ```javascript // Bad - creates memory leak class Component { constructor() { setInterval(() => { this.updateState(); }, 1000); } } // Good - cleanup class Component { constructor() { this.interval = setInterval(() => { this.updateState(); }, 1000); } destroy() { clearInterval(this.interval); } } ``` ### 3. Excessive Re-renders ```javascript // Bad - re-renders on every parent update function Child({ items }) { return items.map(item =>
{item.name}
); } // Good - memoized const Child = React.memo(function Child({ items }) { return items.map(item =>
{item.name}
); }, (prevProps, nextProps) => { return prevProps.items === nextProps.items; }); ``` ## Performance Budget Set and enforce performance budgets: ```json { "budgets": [ { "resourceSizes": [ {"resourceType": "script", "budget": 300}, {"resourceType": "image", "budget": 500}, {"resourceType": "stylesheet", "budget": 50} ], "resourceCounts": [ {"resourceType": "third-party", "budget": 10} ], "timings": [ {"metric": "interactive", "budget": 3000}, {"metric": "first-contentful-paint", "budget": 1500} ] } ] } ``` ## Testing Tools - **Lighthouse**: Automated audits - **WebPageTest**: Real device testing - **Chrome DevTools**: Performance profiling - **bundlephobia.com**: Check package sizes - **web.dev**: Best practices and guides ## Key Takeaways 1. **Measure first**: Use Lighthouse, Web Vitals, RUM 2. **Optimize critical path**: Inline critical CSS, defer JS 3. **Reduce bundle size**: Code splitting, tree shaking 4. **Optimize images**: WebP, lazy loading, responsive images 5. **Cache effectively**: Service workers, HTTP caching 6. **Minimize main thread work**: Web workers, chunking 7. **Monitor continuously**: Real user monitoring 8. **Set budgets**: Enforce performance standards