Site Speed Optimization: Core Web Vitals & Performance in Practice
Site speed isn't just a user-experience issue—it's an SEO ranking signal. Google explicitly factors page experience (including Core Web Vitals) into rankings. A slow-loading page, no matter how good its content, loses on both user patience and search engine evaluation. This article walks from metric definitions, to tooling, to concrete optimization techniques, helping you systematically improve site speed.
Why Speed Affects SEO & Conversions#
Google began incorporating mobile speed as a ranking signal with the 2018 Speed Update, and formally added Core Web Vitals to the ranking system through the 2021 Page Experience Update. Speed isn't the strongest ranking signal—content relevance and quality still rank higher—but on competitive keywords it can be a decisive differentiator.
From a user-behavior perspective, speed's impact on conversion is even more direct:
- Bounce probability increases 32% when load time goes from 1s to 3s
- Bounce probability increases 90% when load time goes from 1s to 5s
- In e-commerce, every 100ms faster loading roughly improves conversion by 1%
In short: the ROI of speed optimization is very high. It serves both search engines and users, and the results are measurable and sustainable.
The Three Core Web Vitals#
Core Web Vitals are Google's three core metrics for measuring real user experience. They focus on loading speed, interactivity, and visual stability, respectively. Google evaluates these metrics using real-world data collected in the Chrome User Experience Report (CrUX).
LCP — Largest Contentful Paint#
LCP measures the loading speed of the page's main content. Specifically, it records the render time of the largest visible element within the viewport (typically a hero image, video poster, or large text block).
| Rating | LCP Threshold | Meaning |
|---|---|---|
| Good | ≤ 2.5s | Users feel the page loads quickly |
| Needs Improvement | 2.5–4.0s | Noticeable wait |
| Poor | > 4.0s | Users likely to leave |
Common causes of poor LCP:
- Slow server response: High TTFB (Time to First Byte), usually due to insufficient server performance or missing caching
- Render-blocking resources: Unoptimized CSS and synchronous JavaScript block page rendering
- Slow resource loading: Hero images uncompressed, not in modern formats, or not preloaded
- Client-side rendering delay: Content depends on JavaScript execution to display
INP — Interaction to Next Paint#
INP measures the page's responsiveness to user interaction. It records the longest (or near-longest) delay from input to the next rendered frame, across all clicks, keyboard, and touch interactions throughout the page's lifecycle.
INP officially replaced FID (First Input Delay) in March 2024. Compared to FID, which only measured the input delay of the first interaction, INP is more comprehensive: it covers all interactions and includes the full response chain (input delay + event processing + presentation delay).
| Rating | INP Threshold | Meaning |
|---|---|---|
| Good | ≤ 200ms | Interactions feel instantaneous |
| Needs Improvement | 200–500ms | Perceptible delay |
| Poor | > 500ms | Interface feels "stuck" |
Common causes of poor INP:
- Long tasks: JavaScript holds the main thread for extended periods, blocking event handling
- Heavy event handlers: Clicks or inputs trigger large amounts of synchronous computation or DOM manipulation
- Too many DOM nodes: An oversized DOM makes reflow and repaint more time-consuming
CLS — Cumulative Layout Shift#
CLS measures the page's visual stability. When page elements unexpectedly shift position during loading, the CLS score increases. A common scenario: you're about to click a button, and suddenly an image loads and pushes the button down, causing you to misclick.
| Rating | CLS Threshold | Meaning |
|---|---|---|
| Good | ≤ 0.1 | Barely perceptible layout shifts |
| Needs Improvement | 0.1–0.25 | Occasional content jumps |
| Poor | > 0.25 | Frequent or large-area layout shifts |
Common causes of high CLS:
- Images/videos without size attributes: The browser doesn't know how much space to reserve and only expands after loading
- Dynamically injected content: Ads, popups, and cookie banners inserted after initial render
- Web font loading: Custom fonts replace system fonts after loading, and text size changes shift the layout
- Late-loading embeds: iframes and embedded widgets alter surrounding layout after loading
Three-Metric Quick Reference#
| Metric | Dimension | Good Threshold | Optimization Focus |
|---|---|---|---|
| LCP | Loading speed | ≤ 2.5s | Server response, image optimization, render path |
| INP | Interactivity | ≤ 200ms | JavaScript execution efficiency, main-thread occupancy |
| CLS | Visual stability | ≤ 0.1 | Size reservation, font loading, dynamic content control |
Speed Testing Tools#
Before optimizing speed, you need to know how you currently perform. These tools provide performance data from different angles:
| Tool | Data Source | Use Case |
|---|---|---|
| PageSpeed Insights | Lab (Lighthouse) + Real users (CrUX) | The most popular all-in-one checker; enter a URL to see Core Web Vitals and optimization suggestions |
| Chrome Lighthouse | Lab simulation | Built into DevTools; iterate in a local environment, ideal for real-time checks during development |
| Chrome DevTools Performance | Lab simulation | Detailed performance timeline; pinpoint the exact code locations of long tasks, layout shifts, and render-blocking |
| CrUX Dashboard | Real users | 28 days of real user experience data—this is the data source Google uses for ranking |
| Web Vitals extension | Current browser | Chrome extension that shows LCP/INP/CLS in real time while browsing; quickly judge page performance |
| Search Console | Real users | The Core Web Vitals report groups site URLs by Good/Needs Improvement/Poor |
Optimizing Images#
Images are usually the largest resources on a page and the most common LCP bottleneck. Image optimization is the most direct and effective way to improve load speed.
Choose Modern Formats
WebP reduces file size by 25–35% on average versus JPEG, and AVIF reduces it a further 20%. The <picture> tag lets you serve different formats to different browsers while maintaining compatibility:
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="Descriptive alt text"
width="1200" height="630" loading="lazy">
</picture>
Compression & Responsive Delivery
- Compress: Use tools like Squoosh, Sharp, or ImageOptim. A quality setting of 75–85 is usually the best balance of visual quality and file size.
- Responsive srcset: Provide differently sized images for different screens; avoid loading desktop-sized images on phones.
- Lazy loading: Use
loading="lazy"for below-the-fold images so the browser only loads them as the user scrolls near. Don't lazy-load above-the-fold critical images, or you'll slow LCP. - Size attributes: Always set
widthandheight(or use CSSaspect-ratio) so the browser reserves space and avoids CLS.
Optimizing CSS & JavaScript#
CSS and JavaScript are the two biggest factors affecting render speed and interaction responsiveness.
CSS Optimization
- Minify: Remove whitespace, comments, and redundant characters—typically reduces size 10–30%
- Inline critical CSS: Put the CSS essential for above-the-fold rendering directly in a
<style>tag in<head>, and load the rest asynchronously - Remove unused CSS: Large projects often carry many style rules no longer in use; tools like PurgeCSS help clean them up
- Avoid @import:
@importin CSS creates serial requests—use the<link>tag to load in parallel instead
JavaScript Optimization
- Defer non-critical scripts: Use the
deferorasyncattribute to avoid blocking HTML parsing - Code splitting: Load JavaScript modules on demand rather than downloading all code at once
- Minify and tree-shake: Remove unused code and minify the bundle
- Reduce main-thread occupancy: Break up long tasks (>50ms) into smaller chunks to keep the main thread responsive to interaction
<!-- Render-blocking: only for scripts that must execute before render (e.g., theme toggle) -->
<script src="critical.js"></script>
<!-- defer: executes in order after HTML parsing, doesn't block rendering -->
<script src="app.js" defer></script>
<!-- async: executes as soon as downloaded, order not guaranteed, suited to independent scripts -->
<script src="analytics.js" async></script>
Server & Transport Optimization#
Server response time (TTFB) directly affects LCP. If the server itself is slow, no amount of front-end optimization can make up for it.
| Technique | Effect | How |
|---|---|---|
| CDN | Distributes content to nodes closest to users | Cloudflare, AWS CloudFront, Vercel Edge, etc. |
| Caching strategy | Reduces repeat requests, speeds return visits | Set Cache-Control headers; long-cache static assets + filename hashing |
| Compression | Reduces transfer size 60–80% | Enable Gzip or Brotli (Brotli is 15–20% smaller than Gzip) |
| HTTP/2 or HTTP/3 | Multiplexing, header compression | Modern servers and CDNs usually enable this by default |
| Preconnect | Establishes connections to third-party domains early | <link rel="preconnect" href="..."> |
# Long-cache static assets
location ~* \.(css|js|webp|avif|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Enable Brotli compression
brotli on;
brotli_types text/html text/css application/javascript application/json;
Font Optimization#
Custom fonts are a common CLS and LCP pitfall. Font files are large and slow to load, and the font swap before and after loading causes text flashing (FOIT/FOUT) and layout shifts.
- font-display: swap: Lets the browser show text in a system font first and swap in the custom font once loaded. Avoids text being invisible for long periods.
- Preconnect to font services: If you use Google Fonts, add
<link rel="preconnect">to establish the connection early. - Subsetting: If you only use a small set of characters (e.g., English titles), use a subsetting tool to strip unneeded characters and drastically shrink the font file.
- Use woff2: woff2 is the best-compressed font format today and is supported by all modern browsers.
<!-- Establish the connection to Google Fonts early -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
Layout Stability#
The core idea of CLS optimization: let the browser know every element's size before resources load, avoiding layout jumps when content arrives.
- Images and videos: Always set
width/heightor use CSSaspect-ratio - Ads and embeds: Reserve fixed-size containers for ad slots so loading an ad doesn't expand the page
- Dynamic content: Avoid inserting new content above existing content (like a cookie banner); fix it to the bottom or use a non-layout-affecting overlay instead
- Fonts: Use
font-display: swaptogether withsize-adjustto match the metrics of the system font and custom font as closely as possible
<!-- Good: the browser can reserve space -->
<img src="photo.webp" alt="Caption"
width="800" height="450" loading="lazy">
<!-- Also good: control the aspect ratio with CSS -->
<img src="photo.webp" alt="Caption"
style="aspect-ratio:16/9; width:100%; height:auto" loading="lazy">
<!-- Bad: no size info, layout jumps after loading -->
<img src="photo.webp" alt="Caption">
Mobile Speed#
Google uses mobile-first indexing, and the Core Web Vitals ranking signal is also based on mobile data. Mobile faces greater speed challenges:
- Slower networks: 4G latency is much higher than fiber broadband; on weak networks every request costs more
- Weaker devices: Mid- and low-end phones have far less CPU and memory than desktops, so JavaScript executes more slowly
- Smaller viewports: The above-the-fold content differs, and the LCP element may differ from desktop
Additional mobile optimization tips:
- Use Chrome DevTools Network Throttling to simulate 3G/4G environments for testing
- Reduce the number of third-party scripts—a load that's acceptable on desktop can be disastrous on mobile
- Prioritize the responsiveness of touch interactions (directly affects INP)
- Use
srcsetandsizesto ensure mobile doesn't load desktop-sized images
Speed Optimization Checklist#
LCP Optimization
- Use WebP/AVIF and compress hero images
- Set fetchpriority="high" on above-the-fold critical images; don't lazy-load them
- Inline or preload critical CSS
- Use defer/async for non-critical JS
- Enable a CDN; TTFB < 200ms
- Enable Gzip or Brotli compression
INP Optimization
- Break up JavaScript long tasks over 50ms
- Reduce unnecessary third-party scripts
- Avoid synchronous recomputation/reflow in event handlers
CLS Optimization
- Set width/height on all images and videos
- Reserve fixed sizes for ads and embeds
- Use font-display: swap for fonts
- Don't dynamically insert elements above existing content
General
- Set sensible Cache-Control headers
- Preconnect fonts + use woff2
- PageSpeed Insights Field Data all three "Good"
<link rel="preconnect"> to establish connections early. Every page's LCP element is HTML text, with no need to wait for large images. This is the natural speed advantage of a pure static site.Frequently Asked Questions#
Are Core Web Vitals a ranking factor?
Yes. Since 2021, Google has incorporated Core Web Vitals (LCP, CLS, and INP, which later replaced FID) into the page-experience ranking signal. But it's one of many ranking factors and doesn't determine rank on its own—content relevance and quality still matter most. Between competing pages of similar content quality, a better Core Web Vitals score can be a ranking advantage.
Does a low PageSpeed Insights score always hurt rankings?
Not necessarily. PageSpeed Insights' lab score (Lighthouse) is a simulated result; Google ranking uses real-user data (Field Data) from CrUX. A page with a Lighthouse score of 60 has no negative ranking impact as long as its real-user experience data (LCP, INP, CLS) falls within the "Good" thresholds. Prioritize the Field Data metrics.
What's the difference between INP and the deprecated FID?
FID (First Input Delay) only measured the input delay of the page's first interaction, excluding processing and render time. INP (Interaction to Next Paint) measures the full response time (input delay + processing time + presentation delay) of all interactions throughout the page lifecycle, taking the slowest (or near-slowest) as the final value. INP reflects interaction responsiveness more comprehensively than FID and officially replaced FID in March 2024.
Do small sites also need to focus on speed optimization?
Yes. Speed optimization affects not just SEO but user experience and conversion directly. Even a small site loses visitors if it loads slowly. The good news is that speed optimization is usually simpler for small sites: choosing the right image format, enabling caching, and using a CDN often produce significant results. Pure static sites have a natural speed advantage.