TL;DR
- LCP ≤ 2.5s, INP ≤ 200ms, CLS ≤ 0.1 — Google's "Good" thresholds
- Only 48% of Shopify stores pass all three on mobile
- Core Web Vitals are an official Google ranking factor since June 2021
- Ghost code from uninstalled apps is a top-3 cause of poor CWV
- Typical optimization delivers +15–40% CWV pass rate improvement
What are Core Web Vitals?
Three Google-defined page-experience metrics:
- Largest Contentful Paint (LCP): time to visible main content. Target: ≤ 2.5 seconds
- Interaction to Next Paint (INP): response time to user interactions. Target: ≤ 200 ms (replaced FID in March 2024)
- Cumulative Layout Shift (CLS): sum of unexpected layout shifts. Target: ≤ 0.1
Since Google Page Experience Update (June 2021, full rollout August 2021), CWV is an official ranking factor.
Where Shopify typically fails
Per pagespeedmatters.com 2026: only 48% of Shopify stores rate "Good" across all three on mobile.
Top causes:
- Third-party scripts (apps.shopify.com) — often >50% of load time
- Ghost code from uninstalled apps (251 KB median unused JavaScript)
- Unoptimized images (no AVIF/WebP, no lazy loading)
- Large CLS from app widgets inserting after page load
- theme.liquid with many render-blocking scripts
Optimize LCP
LCP on Shopify is usually caused by large hero images and heavy above-the-fold JavaScript.
Concrete measures:
- Preload hero image:
<link rel="preload" as="image" href="{{ image | image_url }}">in<head> - AVIF/WebP format: Shopify CDN delivers both automatically via
image_urlfilter - Preload fonts +
font-display: swap - Minimize render-blocking JS: defer non-critical scripts
- Don't lazy-load the hero image (classic mistake)
Optimize INP
INP measures not just first click but the worst during the session. Shopify fails here typically due to:
- Overloaded main thread from many third-party scripts
- JavaScript bundles from several apps running in parallel
- Unclean event handler code (long tasks > 50 ms)
Measures:
- Remove third-party scripts (clean up ghost code — see theme cleanup)
- Split long tasks using
scheduler.yield()orsetTimeout(fn, 0) - Code splitting: load only what the current page needs
- Prefer theme extensions over script tags on app install
Optimize CLS
CLS typically arises from:
- Images without
width/heightattributes - Ads/app widgets inserting after DOMContentLoaded
- Fonts with FOIT/FOUT without
font-display: swap - Pop-ups and cookie banners shifting content
Measures:
- Always set image dimensions:
width="800" height="600"or CSSaspect-ratio - Placeholder containers for app widgets: set
min-heightso layout doesn't jump - Skeleton loaders for dynamic content
- Cookie banners: overlay, don't push content
What Shopify handles automatically
- Image optimization via CDN
- HTTP/2, Brotli compression
- Caching headers
What Shopify does NOT do automatically:
- Remove ghost code (see GhostCode)
- Detect app-script conflicts
- Optimize theme code
Measurement and monitoring
- Lighthouse (ad-hoc):
https://pagespeed.web.dev/ - Core Web Vitals report in Google Search Console (field data from Chrome UX Report)
- Shopify Theme Performance Report: admin → Online Store → Themes → Customize → Performance
Target: 75th percentile in field data, not just lab data in Lighthouse.
The 48-hour plan
- Day 1 AM: Lighthouse baseline for top-3 pages (Home, Collection, Product)
- Day 1 PM: GhostCode scan + cleanup
- Day 1 evening: Hero image preload, font preload in theme.liquid
- Day 2 AM: Set image dimensions on all templates
- Day 2 PM: Re-audit Lighthouse, compare
- Day 2 evening: Set up Search Console CWV report for ongoing monitoring
Expected LCP gain: 0.5–1.5 seconds. INP −20 to −80 ms.
Next steps
- This week: Lighthouse baseline + first ghost code scan
- Next week: Track CWV report in Search Console regularly
- Ongoing: Test every app install for performance impact (before/after Lighthouse)
Further reading: Clean Up Shopify Theme: 12 Steps · Remove Ghost Code · Shopify Performance Tips