Core Web Vitals
-
FCP (First Contentful Paint) Time taken to render the first piece of DOM content.
-
LCP (Largest Contentful Paint) Time taken to render the largest visible content element in the viewport.
-
CLS (Cumulative Layout Shift) Measures the visual stability. Layout shifts occur when visible elements change position between frames (e.g., image loads late and pushes paragraph).
Best Practice: Set explicit width and height for images and other dynamic content to prevent layout shifts.
-
FID (First Input Delay) Measures the delay from user interaction to the browser processing the event.
-
INP (Interaction to Next Paint) (New from March 2024) Measures the time from user interaction to the next visual change. Captures UI responsiveness better than FID.
Best Practices & Tips
-
Disable Chrome Extensions & Eject Dev Tools when using Lighthouse for accurate metrics.
-
Use Priority Hints (
importance="high") to prioritize critical resources. -
CSS Loading is Render-Blocking
-
Avoid Base64 Images in CSS: Increases CSS parsing time.
-
Use Specific CSS Selectors:
.nav > ul > li > ais faster than.nav ul li a -
Script Tag Placement:
- Scripts after CSS ensure CSS loads and applies before script parsing.
- Use
asyncordeferas needed.
Async Loading CSS (Shopify Pattern)
<link rel="stylesheet" href="my.css" media="print" onload="this.media='all'">
<noscript>
<link rel="stylesheet" href="my.css">
</noscript>- Reduces CSS load priority until it’s needed.
Networking & Resource Optimization
Page Load Sequence
[DNS] → [TCP] → [TLS] → [HTTP Request]
Hints
| Hint | Cost | Benefit |
|---|---|---|
| DNS Prefetch | Low | Low |
| Link Prefetch | Mid | High |
| Prerender | Very High | Very High |
- DNS Prefetch: Resolve DNS early.
- Preconnect: Prepares TCP, TLS early.
- Preload: Forces immediate load; console warns if misused.
- Prerender: Use in login to preload dashboard.
Avoid Layout Thrashing
- Happens when styles are updated and immediately read.
- Forces sync layout calculations. (Purple bar in Chrome Perf tab)
Optimizing LCP (Source)
- Use
posterattribute in video tags. - Avoid background images in CSS for key visuals. Use
<img>withpreload.
Memory Usage Monitoring
- Use
measureUserAgentSpecificMemory()to monitor memory.
RequestAnimationFrame (rAF)
- Most screens update at 60Hz; rAF aligns with display refresh.
setTimeout(fn, 0)executes ~4.7ms later.setTimeout(fn, 100/60)is roughly one frame.requestAnimationFrame(fn)fires before style and layout.
Correct Usage Example:
button.addEventListener("click", () => {
box.style.transform = "translateX(1000px)";
box.style.transition = "transform 1s ease-in-out";
// One rAF is not enough, use two
requestAnimationFrame(() => {
requestAnimationFrame(() => {
box.style.transform = "translateX(500px)";
});
});
// OR use computed style to force layout
// getComputedStyle(box).transform;
});Execution Order: [JavaScript] → [rAF] → [Style] → [Layout] → [Paint]
Some browsers process rAF after layout; test accordingly.
Microtasks vs Macrotasks
// Won't block UI
function loop() {
setTimeout(loop, 0);
}
loop();
// Will block UI (runs in microtask queue)
function loop() {
Promise.resolve().then(loop);
}
loop();- Microtasks (e.g., Promises) can block rendering if used recursively.
Performance APIs
performance.getEntries()— captures up to 150 resources by default.
Speed Index
- Average time at which visible content appears.
- JS threads assigned per domain.
- Use
requestIdleCallback()to defer non-critical tasks.
Web Performance Resources
Articles & Guides
- Browser Rendering Optimization - Udacity
- Rendering Performance Guide - web.dev
- Runtime Performance Checklist - Perfplanet
- A Developer Guide to Rendering Performance - Vimeo
- High Performance Animations - HTML5 Rocks
- CSS Triggers
- Beginner’s Guide to Chrome Tracing - Nolan Lawson
- CSS Runtime Performance - YouTube
- Fixing Memory Leaks in Web Applications - Nolan Lawson
- Fuite - Memory Leak Detection Tool
- Why our build got 15x slower with Webpack 5 - Tines
- Keep Webpack Fast - Slack Engineering
- CSS Runtime: Style → Layout → Paint → Composite - YouTube
- Speeding Up the JS Ecosystem - ESLint
- Dropbox TTVC - Visual Completion Metric
- Calibre Blog - Web Performance & SEO
- Large File Upload with Web Workers
- DOM Size and Interactivity - web.dev
- WebP for Faster Page Loads - Meesho
- Doordash Frontend Performance Lessons
- Extracting JS Source Code from Source Maps
- Performance Chapter - HTTP Archive Almanac
- Booking.com’s Multi-Platform Design System
- Priority Hints - MacArthur
- Send HTTP Request on Page Exit
- Facebook Frontend Optimization
- Perfume.js - Web Performance Library
- Web Performance Starter Guide
- Initial Web Performance Audit Tips
Tools
- SVGO - SVG Optimizer
- 3rdParty.io - Monitor Third-Party Scripts
- Speedlify - Web Performance Over Time
- Performance API Page Load Timer
- Polypane - Responsive Design Browser
- Statoscope - Webpack Stats Analyzer
- Trace Cafe - Shareable Chrome Traces
- Spall Web Profiler
- npmgraph.js.org - Dependency Graph
- Fuite - Memory Leak Detection
- Lighthouse Treemap
- Estimo - JS Execution Time Estimator
- Tracium - Chrome Trace Parser
- Afterframe
- Boomerang - Real User Measurement
- Perfmap
- Performance Bookmarklet
- pwmetrics
- capo.js - HTML Head Order Checker
CSS
- 3D CSS Notes
- Content-Visibility - web.dev
- CSS Tricks: Content Visibility
- Avoid Layout Thrashing
- CSSFact - CSS Rule Reduction
Performance Tips
- Tune the Web Resources
- CSS Wizardry
- Priority Hints - Etsy
- Frontend Performance Optimization Guide
- RAIL Performance Model - web.dev
- Browser Preloader Deep Dive
- Barrel Files and Build Performance
- JS Self-Profiling API
- https://stackinsight.dev/blog/memory-leak-empirical-study/
- Monitor and improve your web app’s load performance
Blogs
- Tune the Web Blog
- Shopify Performance Blog
- Smashing Magazine: Global Audience Optimization
- Nitropack Blog
- Andy Davies Blog
- web.dev Performance Learning
- Web Performance PPT Collection - nicj.net
Dev Tools
Core Web Vitals & INP
- INP Core Web Vital - Shopify
- INP Workshop with Code Examples
- Optimize INP - web.dev
- web-vitals Script by GoogleChrome
- Custom Metrics with User Timing API
- User Timing and Custom Metrics - SpeedCurve
- ux-capture - Performance.mark Tracking
- Lighthouse Criticism - dev.to
Tips & Tricks
Speeding Up JavaScript Ecosystem (Series)
https://www.developerway.com/posts/client-side-rendering-flame-graph