Quality, Performance, Accessibility, and Shipping Intermediate 12 min read
Performance Audit Checklist
A comprehensive checklist for auditing and optimizing Shopify theme performance, covering images, JavaScript, CSS, and Core Web Vitals.
Fast themes convert better. A comprehensive performance audit ensures your theme loads quickly, responds instantly, and provides a smooth shopping experience.
Core Web Vitals
Google’s Core Web Vitals are the key metrics for user experience:
| Metric | Target | What It Measures |
|---|---|---|
| LCP (Largest Contentful Paint) | < 2.5s | Loading performance |
| INP (Interaction to Next Paint) | < 200ms | Interactivity |
| CLS (Cumulative Layout Shift) | < 0.1 | Visual stability |
Performance Audit Checklist
Images
## Image Optimization
- [ ] Use `image_url` with appropriate widths- [ ] Include `srcset` for responsive images- [ ] Add `loading="lazy"` for below-fold images- [ ] Add `loading="eager"` for hero/LCP images- [ ] Set explicit `width` and `height` attributes- [ ] Use `fetchpriority="high"` for LCP image- [ ] Avoid oversized images (match display size)- [ ] Use WebP format when possibleImage Best Practices
{# Hero image (LCP candidate) #}{{ product.featured_image | image_url: width: 1200 | image_tag: loading: 'eager', fetchpriority: 'high', width: product.featured_image.width, height: product.featured_image.height, sizes: '(max-width: 768px) 100vw, 50vw'}}
{# Product grid images (lazy loaded) #}{{ product.featured_image | image_url: width: 600 | image_tag: loading: 'lazy', width: 600, height: 600, sizes: '(max-width: 768px) 50vw, 25vw'}}JavaScript
## JavaScript Optimization
- [ ] Load scripts with `defer` attribute- [ ] Minimize third-party scripts- [ ] Use native JS over large libraries- [ ] Lazy load non-critical scripts- [ ] Avoid render-blocking JavaScript- [ ] Split code by template (load only what's needed)- [ ] Use event delegation for dynamic content- [ ] Debounce/throttle scroll and resize handlersJavaScript Loading
{# Defer non-critical scripts #}<script src="{{ 'theme.js' | asset_url }}" defer></script>
{# Lazy load scripts for specific features #}{%- if template.name == 'product' -%} <script src="{{ 'product.js' | asset_url }}" defer></script>{%- endif -%}CSS
## CSS Optimization
- [ ] Inline critical CSS for above-fold content- [ ] Load non-critical CSS asynchronously- [ ] Remove unused CSS selectors- [ ] Minimize CSS bundle size- [ ] Avoid `@import` in CSS files- [ ] Use CSS custom properties for theming- [ ] Minimize specificity and nestingCSS Loading Strategies
{# Critical CSS inline #}<style> {# Above-fold styles #} .header { ... } .hero { ... }</style>
{# Non-critical CSS with preload #}<link rel="preload" href="{{ 'theme.css' | asset_url }}" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link rel="stylesheet" href="{{ 'theme.css' | asset_url }}"></noscript>Fonts
## Font Optimization
- [ ] Use `font-display: swap` or `optional`- [ ] Preload critical fonts- [ ] Limit font weights and styles- [ ] Use system fonts as fallbacks- [ ] Subset fonts if using custom uploadsFont Loading
{# Preload critical fonts #}<link rel="preload" href="{{ settings.type_heading_font | font_url }}" as="font" type="font/woff2" crossorigin>
{# Font face with swap #}{{ settings.type_heading_font | font_face: font_display: 'swap' }}Third-Party Resources
## Third-Party Optimization
- [ ] Audit all third-party scripts- [ ] Remove unused apps/scripts- [ ] Lazy load chat widgets- [ ] Use facade patterns for embeds- [ ] Self-host critical third-party resources- [ ] Add `dns-prefetch` for external domainsResource Hints
{# DNS prefetch for external domains #}<link rel="dns-prefetch" href="https://cdn.shopify.com"><link rel="preconnect" href="https://cdn.shopify.com" crossorigin>
{# Preload critical resources #}<link rel="preload" href="{{ 'theme.css' | asset_url }}" as="style">Layout Stability (CLS)
## Layout Stability
- [ ] Reserve space for images (aspect-ratio or padding)- [ ] Reserve space for dynamic content- [ ] Avoid inserting content above existing content- [ ] Use CSS transforms for animations- [ ] Set explicit dimensions for ads/embeds- [ ] Preload fonts to prevent FOUT/FOITPreventing Layout Shifts
/* Reserve space for images */.product-card__image-wrapper { aspect-ratio: 1; background: var(--color-background-subtle);}
/* Reserve space for lazy-loaded content */.product-recommendations { min-height: 400px;}Liquid Optimization
## Liquid Performance
- [ ] Minimize Liquid loops inside loops- [ ] Use `limit` on large collections- [ ] Cache repeated calculations with `assign`- [ ] Avoid unnecessary `render` calls- [ ] Use `{% raw %}{% liquid %}{% endraw %}` for multiple operations- [ ] Paginate large collectionsLiquid Best Practices
{# Good: Cache repeated values #}{%- assign product_price = product.price | money -%}{%- for i in (1..3) -%} {{ product_price }}{%- endfor -%}
{# Good: Limit collection loops #}{%- for product in collection.products limit: 12 -%} {% render 'product-card', product: product %}{%- endfor -%}
{# Good: Use liquid tag for multiple operations #}{%- liquid assign featured = collection.products | where: 'available' | first assign price = featured.price | money assign title = featured.title-%}Testing Tools
Shopify Tools
## Shopify Performance Testing
- [ ] Theme Editor Performance report- [ ] Lighthouse via Chrome DevTools- [ ] Web Vitals Chrome extension- [ ] Shopify Theme Inspector (Chrome extension)External Tools
## External Testing Tools
- [ ] PageSpeed Insights- [ ] WebPageTest.org- [ ] GTmetrix- [ ] Chrome DevTools (Performance tab)- [ ] Chrome DevTools (Network tab, slow 3G)Performance Budget
Set limits for your theme:
| Resource | Budget |
|---|---|
| Total page weight | < 2MB |
| JavaScript | < 300KB |
| CSS | < 100KB |
| Images (initial) | < 500KB |
| Fonts | < 100KB |
| Third-party | < 200KB |
Audit Template
# Performance Audit Report
**Date:** 2024-01-15**Page:** Homepage / Collection / Product**Device:** Mobile / Desktop
## Metrics (Before)
- LCP: \_\_\_s- INP: \_\_\_ms- CLS: \_\_\_- Total page size: \_\_\_KB- Requests: \_\_\_
## Issues Found
1.2.3.
## Fixes Applied
1.2.3.
## Metrics (After)
- LCP: \_\_\_s- INP: \_\_\_ms- CLS: \_\_\_- Total page size: \_\_\_KB- Requests: \_\_\_Quick Wins
Immediate Impact
- Lazy load below-fold images
- Defer non-critical JavaScript
- Preload LCP image
- Remove unused apps
- Optimize hero image size
Medium Impact
- Inline critical CSS
- Implement font-display: swap
- Add resource hints
- Paginate collections
- Use native lazy loading
Practice Exercise
Audit a theme page:
- Run Lighthouse on mobile
- Identify top 3 performance issues
- Implement fixes
- Re-run Lighthouse
- Document improvement
Key Takeaways
- Core Web Vitals are the key metrics
- Images are often the biggest opportunity
- JavaScript should be deferred and minimal
- Layout stability requires reserved space
- Testing tools help identify issues
- Performance budgets keep you accountable
- Quick wins provide immediate improvement
What’s Next?
The next lesson covers the Accessibility Checklist for inclusive theme development.
Finished this lesson?
Mark it complete to track your progress.
Discussion
Loading comments...