Optimizing Core Web Vitals for Shopify Stores
Share
Achieve perfect Lighthouse scores with these proven optimization strategies for faster page loads and better SEO. Learn how to optimize LCP, FID, and CLS for your Shopify store.
Understanding Core Web Vitals
Core Web Vitals are three key metrics that Google uses to measure user experience:
- • LCP (Largest Contentful Paint) - Loading performance (target: <2.5s)
- • FID (First Input Delay) - Interactivity (target: <100ms)
- • CLS (Cumulative Layout Shift) - Visual stability (target: <0.1)
Optimizing LCP
The Largest Contentful Paint is typically your hero image or main product image. Here's how to optimize it:
<!-- Preload critical images -->
<link rel="preload"
as="image"
href="hero-image.jpg"
fetchpriority="high">
<!-- Use responsive images -->
<img srcset="image-400.jpg 400w,
image-800.jpg 800w,
image-1200.jpg 1200w"
sizes="(max-width: 600px) 400px,
(max-width: 900px) 800px,
1200px"
src="image-800.jpg"
loading="eager"
fetchpriority="high"
alt="Hero Image">
Reducing JavaScript Execution
Heavy JavaScript is the #1 cause of poor FID scores. Implement code splitting and defer non-critical scripts:
// Lazy load non-critical features
const loadQuickView = () => {
return import('./quick-view.js');
};
// Defer third-party scripts
<script defer src="analytics.js"></script>
// Use Intersection Observer for below-fold features
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
loadFeature();
observer.disconnect();
}
});
});
Eliminating Layout Shift
CLS happens when elements move unexpectedly. Reserve space for dynamic content:
/* Reserve space for images */
.product-image {
aspect-ratio: 1 / 1;
background: var(--skeleton-bg);
}
/* Use CSS containment */
.product-card {
contain: layout style paint;
}
/* Set font-display for web fonts */
@font-face {
font-family: 'CustomFont';
font-display: swap;
src: url('font.woff2');
}
Image Optimization Strategy
Shopify's image CDN is powerful - use it correctly:
// Generate optimal image URLs
const getOptimizedImageUrl = (src, width) => {
return src
.replace('.jpg', `_` + width + 'x.jpg')
.replace('.png', `_` + width + 'x.png`);
};
// Lazy load with native loading attribute
images.forEach((img, index) => {
img.loading = index < 3 ? 'eager' : 'lazy';
img.decoding = 'async';
});
App Performance Budget
Third-party apps can destroy performance. Set a strict budget:
- • Maximum 3 apps that add frontend code
- • Each app must score <100ms on Speed Index
- • Use async loading for all app scripts
- • Regular performance audits of installed apps
Performance Checklist
- ✓ Images optimized and lazy loaded
- ✓ Critical CSS inlined, rest deferred
- ✓ JavaScript code-split and lazy loaded
- ✓ Web fonts optimized with font-display
- ✓ Third-party scripts loaded asynchronously
- ✓ Layout shifts eliminated with reserved space
- ✓ Server response time <600ms
- ✓ Resource hints (preconnect, dns-prefetch) used