The Starting Point
A luxury jewelry brand came to us with a problem they could feel but could not diagnose. Their Shopify store was slow. Not "kind of slow" — painfully slow. Their Lighthouse performance score was 34. Their LCP (Largest Contentful Paint) was 4.2 seconds on mobile. Their bounce rate had climbed to 68% over the past six months. And their Google rankings were dropping — they had fallen from page 1 to page 2 for three of their top five keywords.
They had tried speed optimization apps. They had tried switching themes. Nothing worked. That is when they called us.
The Audit: Finding the Bottlenecks
We run a 40-point performance audit on every speed optimization project. Here is what we found on this store:
JavaScript Bloat: 2.4MB of Scripts
The store had 14 Shopify apps installed. Eight of them injected JavaScript into every page load — whether their functionality was needed on that page or not. A reviews app loaded 340KB of JavaScript on the homepage, where there were no reviews. A currency converter loaded 180KB even though the store only sold in USD.
Total JavaScript payload: 2.4MB. For context, the entire JavaScript bundle of a well-optimized Shopify store should be under 200KB.
Unoptimized Images: 8.6MB on Homepage
The hero banner was a 3.2MB PNG. Product images in the featured collection were full-resolution JPEGs averaging 800KB each. None had responsive srcset attributes — mobile users were downloading desktop-sized images. No lazy loading was implemented, so all 22 images on the homepage loaded simultaneously.
Render-Blocking CSS
The theme loaded three separate CSS files synchronously in the head — 340KB total. Only about 15% of this CSS was needed for the initial viewport. The rest was for product pages, cart drawers, and components that were not visible until user interaction.
Excessive Liquid Rendering
The homepage template had nested for-loops iterating through all products in four different collections — fetching 200+ products just to display 12. Each iteration included a full product card partial with metafield lookups. Server-side rendering time was 1.8 seconds.
The Fix: Step by Step
Step 1: App Audit and Script Removal (Day 1-2)
We audited all 14 apps and categorized them:
- Keep (4 apps): Klaviyo, Yotpo Reviews, Recharge, ShipStation — all essential for business operations
- Remove (6 apps): Currency converter (not needed), two abandoned cart apps (Klaviyo handles this), a popup app (replaced with native code), an SEO app (we handle SEO manually), a speed optimization app (ironic — it was making things slower)
- Optimize (4 apps): Loaded remaining app scripts conditionally — reviews JS only on product pages, Recharge JS only on subscription products
Result: JavaScript reduced from 2.4MB to 420KB. A 82% reduction.
Step 2: Image Optimization (Day 2-3)
- Converted all images to WebP format with AVIF fallback
- Implemented responsive srcset with breakpoints at 400px, 800px, and 1200px
- Added lazy loading for all below-the-fold images
- Compressed hero banner from 3.2MB to 68KB with no visible quality loss
- Set explicit width and height attributes on all images to prevent CLS
Result: Total image payload reduced from 8.6MB to 340KB. A 96% reduction.
Step 3: Critical CSS Inlining (Day 3-4)
- Extracted the CSS needed for the initial viewport (above the fold)
- Inlined it directly in the
— 14KB total - Loaded the remaining CSS asynchronously using
media="print"with anonloadhandler - Purged unused CSS rules from the theme — removed 180KB of dead selectors
Result: Render-blocking CSS eliminated. First paint time reduced by 1.1 seconds.
Step 4: Liquid Template Refactoring (Day 4-5)
- Replaced nested product loops with paginated collection fetches — loading only the 12 products displayed
- Eliminated redundant metafield lookups by caching values in Liquid variables
- Moved non-critical sections (Instagram feed, recently viewed) to lazy-loaded sections
- Reduced Liquid rendering time from 1.8s to 0.3s
Result: Server response time (TTFB) reduced from 2.1s to 0.4s.
Step 5: Resource Hints and Preloading (Day 5)
- Added
preconnecthints for Shopify CDN, Google Fonts, and Klaviyo - Preloaded the hero image and primary font file
- Implemented
prefetchfor the most-visited product pages - Self-hosted Google Fonts to eliminate the extra DNS lookup
Result: LCP reduced by an additional 0.3 seconds.
The Results
| Metric | Before | After | Improvement |
|---|---|---|---|
| Lighthouse Score | 34 | 96 | +62 points |
| LCP (mobile) | 4.2s | 0.9s | -79% |
| Total Page Weight | 11.8MB | 780KB | -93% |
| JavaScript | 2.4MB | 420KB | -82% |
| TTFB | 2.1s | 0.4s | -81% |
| CLS | 0.32 | 0.04 | -87% |
| Bounce Rate | 68% | 34% | -50% |
Within 30 days of the optimization going live, the store saw:
- Organic traffic: +38% (Google re-indexed the faster pages and rankings recovered)
- Conversion rate: 1.2% → 2.8% (a 133% increase)
- Revenue: +$42,000/month increase attributed to speed improvements
Lessons Learned
Apps are the number one speed killer on Shopify. Every app you install adds JavaScript. Most do not load conditionally. Audit your apps quarterly — if you are not actively using it, uninstall it completely.
Images are almost always the biggest payload. WebP conversion with responsive srcset should be standard practice. There is no reason to serve a 2000px image to a 400px mobile screen.
The Shopify speed score in admin is misleading. It uses a simplified metric. Use Lighthouse and WebPageTest for real performance data. Test on a throttled 3G connection to see what your mobile customers actually experience.
Speed optimization is not a one-time project. New apps, content updates, and theme changes reintroduce performance debt. Monitor continuously or schedule quarterly audits.