On this page
CONTEXT
What are Core Web Vitals and why do they matter for Shopify?
Core Web Vitals are three specific, measurable metrics Google defined to standardize what "fast" actually means:
-
LCP (Largest Contentful Paint) — how long until the largest visible element (usually a hero image or headline) finishes rendering. Google's threshold for "good": 2.5 seconds or less.
-
INP (Interaction to Next Paint) — how long the page takes to visibly respond after someone clicks or taps. Threshold: 200 milliseconds or less.
-
CLS (Cumulative Layout Shift) — how much visible content shifts around while the page loads. Threshold: 0.1 or less.
A closely related metric, Total Blocking Time (TBT), measures how long the main thread is tied up by scripts that block the browser from responding. Any task over 50 milliseconds counts.
For a Shopify store, these numbers matter for two reasons. First, they're a confirmed Google ranking signal: page experience affects search visibility. Second, a retailer has tested loading time against revenue. In an A/B test at the online fashion retailer Zalando, a 100 ms improvement in loading time led to a 0.7% uplift in revenue per session. That's one retailer's test, so I won't turn it into a dollar figure for your store.
A lab score can improve without the underlying cause getting fixed. When that happens, real customer experience doesn't move, and neither does conversion.
SELF-AUDIT
How do I check my Shopify store's Core Web Vitals score?
There are two different kinds of data, and conflating them is the most common mistake:
-
Field data (Chrome UX Report, or "CrUX") reflects what real visitors on real devices actually experienced over the past 28 days. This is what Google uses for ranking, and it's the number that matters most, though it requires enough traffic to a page to generate a sample.
-
Lab data (Lighthouse, PageSpeed Insights, GTmetrix) simulates a single page load under controlled conditions. It's useful for diagnosing why a page is slow, but it moves independently of what real visitors experience.
To check your store:
-
PageSpeed Insights (pagespeed.web.dev) — enter your URL, run it on mobile (Google weights mobile more heavily), and check both the field data box (if present) and the lab diagnostics below it.
-
Search Console → Core Web Vitals report — shows field data across your whole site, grouped by URL pattern, so you can see which templates (product, collection, homepage) are failing.
-
Chrome DevTools → Lighthouse tab — run locally for a repeatable lab test during development, before and after a change.
Run this on your product page template. Product pages are where review, upsell and bundle apps load their scripts, so they're the likeliest place to find the problem.
ROOT CAUSES
What's causing my Shopify store's slow LCP?
LCP problems on Shopify stores trace back to a small set of recurring causes:
-
The largest element is render-blocked by something upstream. If a hero image or headline can't paint until a script finishes executing first, the LCP timer keeps running even though the actual content is ready.
-
Images aren't sized or formatted correctly. Missing width/height attributes, no lazy-loading below the fold, and non-WebP formats all add avoidable time to the largest paint.
-
Third-party scripts compete for the main thread before the page can finish rendering. Each long task (a script running for more than 50 ms without a break) is a moment the browser can't respond to the visitor or finish painting the page.
-
Fonts aren't preloaded, causing a flash of invisible or swapped text that can itself count as the largest paint event, shifting the measurement.
Apps, scripts, and page builder overhead competing for the same rendering budget cause most LCP problems on Shopify stores. A generic speed checklist doesn't move the number, because it treats symptoms without identifying which specific script or asset is responsible on your store.
Want to know exactly what's slowing your store's LCP?
The Diagnostic Audit names the scripts behind your LCP, on your own pages.
PAGE BUILDERS
How do page builders affect Core Web Vitals?
Page builder apps add their own rendering layer on top of the theme. Instead of a section rendering directly from Liquid, the builder's JavaScript has to load, parse its own configuration, and construct the DOM client-side before the content appears.
That pattern causes two specific Core Web Vitals problems:
-
LCP delay — if the builder is responsible for the hero section or a major above-the-fold block, the largest element can't paint until the builder's script fully executes, which takes longer than the download alone.
-
TBT/INP overhead — the builder script itself is a long-running task on the main thread, competing with every other app script for the same execution window.
Page builders solve a real problem: giving non-technical teams control over layout without touching code. The tradeoff is architectural. Every layer of client-side rendering between the browser and the visible content adds latency that a native Liquid section, rendered server-side, skips entirely.
CORE WEB VITALS
Why Page Builders Hurt Core Web Vitals (And How to Go Native)Why page builder apps slow down LCP and TBT, and what the theme's own sections do instead.Read →
THIRD-PARTY SCRIPTS
How do I fix third-party scripts blocking my main thread?
Most third-party scripts don't need to be removed. They need to load differently. Three patterns cover the majority of fixes:
-
Defer non-critical scripts. Anything that doesn't need to run before the page is interactive, most marketing pixels, chat widgets, and email capture tools, can load after the main content instead of competing with it for the initial render window.
-
Lazy-load below-the-fold functionality. A review widget or a recommendation carousel that isn't visible on initial load doesn't need to execute on initial load either. Loading it when it scrolls into view, via IntersectionObserver, removes its cost from the metrics that matter most.
-
Move what can move server-side. Some tracking and marketing scripts don't need to run in the browser at all. Shopify's Web Pixels API lets certain events fire server-side instead of adding client-side JavaScript weight.
Email apps are a common case: the default snippet often loads early and adds to TBT when it isn't deferred. A deferred-loading pattern removes that main-thread cost without breaking email capture.
Scripts that some uninstalled apps wrote into your theme don't disappear on their own. Ghost code, leftover snippets and scripts from apps that are no longer active, adds the same kind of main-thread weight as an app that's still running, with none of the functionality. Check for it in the same pass as your third-party script review.
CORE WEB VITALS
How to load an email app's script without blocking the main threadA loading pattern that keeps the email app's script off the main thread until a visitor interacts, without breaking email capture.Read →
APP BLOAT
The Invisible Tax: Why 'Deleted' Apps Are Still Loading on Your SiteGhost code from uninstalled apps adds JavaScript overhead to every page load — even apps you removed months ago.Read →