Speed, Stability, and Interaction
Performance Budget & Core Web Vitals Standard
Fast pages win attention and trust. This standard sets clear targets for LCP, INP, and CLS, defines template-level budgets, and gives you copy-paste patterns for images, fonts, JavaScript, and third-parties. It follows guidance from web.dev Core Web Vitals, Google Search Central, and MDN.
Objective and scope
Define a single performance policy for all public pages. The goal is simple: hit Core Web Vitals for most users, most of the time, on real devices and networks. Core Web Vitals are a set of user-centered metrics highlighted by Google at web.dev. Search Central treats performance as part of a helpful user experience at helpful content.
INP replaced FID in 2024. Targets below reflect the current thresholds. See INP guidance.
Targets and definitions
LCP – Largest Contentful Paint
Target: good at ≤ 2.5 s for the 75th percentile of page loads. The LCP element is usually a hero image or a large text block. See LCP.
INP – Interaction to Next Paint
Target: good at ≤ 200 ms for the 75th percentile of interactions. Focus on input delay, processing, and presentation delay. See INP.
CLS – Cumulative Layout Shift
Target: good at ≤ 0.1. Prevent shifts with fixed dimensions, reserved space, and careful font loading. See CLS.
Other helpful metrics: First Contentful Paint (FCP), Time to First Byte (TTFB), and Total Blocking Time (TBT) during lab testing. Definitions on MDN Performance.
Template-level budgets
Budgets keep teams honest. Set ceilings for requests and bytes by template. Block merges that break them.
Template | Requests (max) | JS (kb, parsed) | CSS (kb) | Images total (kb) | LCP resource (kb) | Targets |
---|---|---|---|---|---|---|
Home | 80 | 300 | 120 | 700 | 180 | LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1 |
Article | 50 | 180 | 90 | 600 | 160 | LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1 |
Product/Solution | 70 | 260 | 110 | 650 | 180 | LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1 |
Pricing | 60 | 220 | 110 | 550 | 160 | LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1 |
Use these as starting points. Tighten once you see real-user data in the Chrome UX Report at CrUX and in Search Console’s Core Web Vitals reports at Search Console.
LCP strategy
Most LCP issues come from a heavy hero image, render-blocking CSS or JS, or slow server responses.
Hero image plan
- Use AVIF or WebP with a JPEG fallback
- Provide width descriptors and a realistic sizes
- Set fetchpriority=”high” on the LCP image
- Include width and height to reserve space
Patterns at MDN picture and LCP optimization.
CSS and render path
- Inline only critical CSS for above-the-fold layout
- Defer non-critical CSS with media or load async
- Remove unused CSS at build time
Server and TTFB
- Use CDN caching and edge HTML where possible
- Compress with Brotli, serve over HTTP/2 or HTTP/3
- Warm critical pages after deploy
Hero example
<link rel="preload" as="image"
imagesrcset="/img/hero-w1200.avif 1200w, /img/hero-w1600.avif 1600w"
imagesizes="(min-width: 1024px) 1000px, 90vw"
href="/img/hero-w1600.avif">
<picture>
<source type="image/avif" srcset="/img/hero-w800.avif 800w, /img/hero-w1200.avif 1200w, /img/hero-w1600.avif 1600w" sizes="(min-width: 1024px) 1000px, 90vw">
<source type="image/webp" srcset="/img/hero-w800.webp 800w, /img/hero-w1200.webp 1200w, /img/hero-w1600.webp 1600w" sizes="(min-width: 1024px) 1000px, 90vw">
<img src="/img/hero-w1200.jpg" width="1600" height="900" alt="Team reviewing a content performance dashboard"
loading="eager" fetchpriority="high" decoding="async">
</picture>
More patterns in the Image and Media Optimization Standard on this site and on web.dev Learn Images.
INP strategy
INP measures responsiveness across all interactions. Your job is to keep main thread work small and predictable.
JavaScript budget
- Ship less JS. Split by route and hydrate only what you need
- Use defer for all non-critical scripts
- Move heavy work off the main thread with Web Workers
See INP improvement and MDN on Web Workers.
Interaction ready UI
- Do not attach large listeners on page load
- Use pointerup, click, or change events sparingly
- Provide instant visual feedback while work completes
Third-party control
- Load tags after first interaction when possible
- Use a container and set strict priorities
- Drop unused pixels and legacy A/B libraries
Script pattern
<script defer src="/assets/app.bundle.js"></script>
<script>
// Lazy-init a heavy widget after idle
if ('requestIdleCallback' in window){
requestIdleCallback(() => import('/assets/widget.js'));
} else {
setTimeout(() => import('/assets/widget.js'), 1500);
}
</script>
CLS strategy
Prevent layout shift by reserving space and controlling late-loading UI.
Images and embeds
- Add width and height to every image
- Set aspect ratios for cards and thumbnails
- Use placeholders for iframes and ads
See CLS guide.
Fonts
- Use font-display: swap or optional
- Preload only the critical weight and subset
- Prefer system fonts for UI text
UI loading
- Avoid inserting banners above content without reserved space
- Do not shift content when consent bars appear
.card-thumb{ aspect-ratio:1/1; width:100%; object-fit:cover; border-radius:12px }
Fonts and icon strategy
Fonts often slow the first paint. Keep them lean and predictable.
Serve fewer files
- One family and 2 weights for body and UI
- Subset to needed glyphs
- Self host when possible
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preload" as="font" type="font/woff2" href="/fonts/Inter-500-subset.woff2" crossorigin>
@font-face{
font-family:"Inter";
src: url("/fonts/Inter-500-subset.woff2") format("woff2");
font-weight:500; font-style:normal; font-display:swap;
}
Icons
- Use inline SVG for icons and logos
- Avoid large icon fonts
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2v20M2 12h20"/></svg>
Third-party governance
Third-party scripts are the biggest source of regressions. Treat them like paid calories.
Rule | Policy | Reason |
---|---|---|
Inventory | Quarterly list of all tags and owners | Remove duplicates and dead pixels |
Budget | Max 150 kb third-party JS per template | Protect INP and TBT |
Load timing | Defer or post-interaction when possible | Protect LCP |
Consent | No marketing tags before consent | Privacy compliance |
Chrome team notes the cost of third-parties across many case studies at web.dev third-party.
Resource hints and priorities
Preconnect
Warm connections to critical origins.
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
See preconnect.
Preload
Preload the LCP image and the critical font only.
<link rel="preload" as="font" href="/fonts/Inter-500-subset.woff2" type="font/woff2" crossorigin>
Use with care. Details at preload.
Priority hints
Give the browser a nudge for the LCP element.
<img fetchpriority="high" ... >
Priority hints documented at web.dev.
Monitoring and alerts
Use both field data and lab data. Field data shows real users in the wild. Lab data helps you debug locally.
Search Console
- Core Web Vitals report by URL group
- Page indexing and enhancements
Docs at Core Web Vitals report.
CrUX and RUM
- Chrome UX Report for origin and URL-level trends
- Real-user monitoring for LCP element and INP interactions
CrUX overview at developer.chrome.com.
GA4 events
gtag('event','vitals_report',{
lcp_ms: 1850, cls: 0.03, inp_ms: 120,
page: location.pathname
});
GA4 events and conversions at GA4 events and conversions.
QA gates and release checklist
Make performance a release gate. Block merges when budgets or vitals fail for key templates.
Template | Lab tool | Thresholds | Field guard | Status |
---|---|---|---|---|
Home | Lighthouse CI | Perf score ≥ 90, TBT ≤ 150 ms | CrUX 75p LCP ≤ 2.5 s | Pass |
Article | Lighthouse CI | Perf score ≥ 95, TBT ≤ 100 ms | CrUX 75p INP ≤ 200 ms | Review |
Pricing | WebPageTest | Start render ≤ 1.2 s | CLS ≤ 0.1 | Pass |
Release checklist
- Budgets met for JS, CSS, and images
- LCP image format and priority confirmed
- Fonts subsetted and preloaded correctly
- Third-party tags reviewed and deferred
- No layout shift in the first second of scroll
FAQ
Do Core Web Vitals affect ranking
Performance supports a good user experience, which is a foundation for visibility. Google positions vitals as part of a broader picture that includes content quality. See creating helpful content and Vitals.
How do I find the LCP element
Use the Performance panel in Chrome DevTools or the Web Vitals extension. web.dev shows a step-by-step workflow in the LCP doc.
Is HTTP/3 worth it
It can reduce tail latency and improve mobile performance. Many CDNs support it. MDN covers protocol behavior at HTTP overview.
Should I lazy-load everything
No. Keep the hero image eager and prioritize above-the-fold content. Lazy-load below-the-fold images and embeds. See MDN on loading.