Core Web Vitals for B2B Websites
Most B2B sites fail Core Web Vitals for the same four reasons, and none of them are the framework. Here is what actually moves each metric — and how to stop it regressing.
Sofia Lindqvist
Lead Front-end Engineer
Core Web Vitals matter for two reasons, and only one of them is Google. The ranking effect is real but modest — a tiebreaker rather than a lever. The larger effect is that the same things that make a page score well also make it feel good, and a site that feels sluggish loses people before they read the value proposition.
Most B2B marketing sites fail for the same handful of reasons. Here they are, per metric.
LCP — Largest Contentful Paint
Target: under 2.5 seconds on mobile. Aim for under 2.
The LCP element on a B2B site is almost always the hero heading or the hero image. Four things delay it, in rough order of frequency:
Render-blocking font requests. A Google Fonts stylesheet is a request to a third-party origin that blocks rendering. Self-host fonts, preload the one used above the fold, and use font-display: swap with a metric-adjusted fallback so the swap does not shift layout. Frameworks with a built-in font module do this for you — use it.
Unoptimised hero images. A 2400px JPEG served to a 390px viewport is the most common single cause of a poor mobile LCP. Serve modern formats, size responsively, set explicit dimensions, and mark the hero image as high priority so it is not queued behind other requests.
Client-side rendering of above-the-fold content. If the heading arrives via JavaScript, LCP waits for the bundle to download, parse and execute. Server-render anything above the fold. This is the single largest structural win available and it is a framework choice, not a tuning exercise.
Slow server response. Time to first byte above ~600ms puts a floor under LCP that no front-end work can lift. Static generation or edge caching for marketing pages removes this entirely.
A frequently overlooked one: a hero image inside a client-side carousel or animation library will not begin loading until that library has initialised. If your hero animates, make sure the image itself is in the initial HTML.
CLS — Cumulative Layout Shift
Target: under 0.1. This is the easiest of the three to fix and the most commonly neglected.
Images and iframes without dimensions. Every image needs width and height attributes or an aspect ratio, so the browser can reserve the space before the bytes arrive.
Font swap shifts. When the fallback font has different metrics to the web font, every line of text moves on swap. Modern font loading with an adjusted fallback eliminates this.
Content injected above existing content. Cookie banners, announcement bars and A/B testing tools that push the page down after render. Reserve the space, or render them as overlays that do not affect flow.
Late-loading embeds. Chat widgets, video players and social embeds that appear without reserved space. Give each a placeholder with the final dimensions.
CLS is measured across the whole session, not just initial load — so a shift when someone opens an accordion halfway down the page counts. Test by scrolling and interacting, not just by loading.
INP — Interaction to Next Paint
Target: under 200ms. This replaced First Input Delay in 2024 and is stricter, because it measures every interaction rather than only the first.
Long tasks on the main thread. Any task over 50ms blocks interaction. Analytics initialisation, tag managers and hydration are the usual offenders. Split work, defer what is not needed immediately, and use requestIdleCallback for anything genuinely low priority.
Excessive hydration. Shipping interactive JavaScript for a page that is 90% static text is the most common cause of poor INP on marketing sites. Server components, islands architecture, or simply less JavaScript all address this.
Expensive event handlers. A handler that triggers a large re-render on every keystroke or scroll event. Debounce, throttle, and keep handlers small.
Third-party scripts. Chat widgets, heatmaps, session recorders and marketing tags all compete for the main thread. This is usually the largest single contributor.
The third-party script problem
On most B2B sites we audit, third-party scripts account for 60–80% of total JavaScript execution time. Analytics, tag manager, chat, heatmap, session recording, two attribution pixels and an intent-data tag — each added by a different team, none ever removed.
What helps:
- Audit quarterly. List every script, its owner, and what decision it informs. Anything with no clear answer gets removed.
- Load off the critical path. Defer everything non-essential until after the page is interactive. Almost nothing needs to run before content renders.
- Facade pattern for heavy widgets. Render a lightweight placeholder for chat or video, and load the real thing only on interaction. This typically saves several hundred kilobytes for the majority of visitors who never click it.
- Set a JavaScript budget. A number, agreed in advance, that a pull request cannot exceed without a conversation.
Hold the line after launch
Performance regresses. It regresses because a marketing tag was added, a hero image was replaced with an unoptimised one, or a dependency grew. Without enforcement, every site drifts back.
Three things keep it:
Lighthouse CI in the pipeline, with thresholds that fail the build rather than producing a report someone might read.
Field data, not just lab data. Lab tests run on a fast machine on a good connection. The Chrome UX Report tells you what real users on real devices actually experience, and it is the data Google uses. When lab and field disagree, believe the field.
A named owner. Performance without an owner degrades by default. It does not need to be a big job — a monthly look at the CrUX numbers and the JavaScript budget is usually enough to catch drift early.
What good looks like
A B2B marketing site that is doing this well typically lands around 1.1–1.4s LCP on mobile, CLS under 0.02, and INP under 100ms — while still having analytics, a chat widget and everything marketing needs. It is not a trade-off between performance and functionality. It is a trade-off between performance and not thinking about it.
We build marketing sites with Core Web Vitals as an acceptance criterion rather than an aspiration. See our approach to website design and development, or read how a commerce replatform took LCP from 4.6s to 1.3s.
- #performance
- #Core Web Vitals
- #SEO
- #front-end