From D to A: How We Made SuperBra's Shopify Store Dramatically Faster

Bra Girl lingerie pink background

SuperBra is a Dutch lingerie and swimwear retailer with a loyal customer base, three physical stores and a Shopify storefront that carries a lot of weight. When we looked at the site in October 2026, it worked, but it did not feel fast. On GTmetrix the home page sat at a D for performance (60/100) and the product pages were worse (62 overall, performance 47). Over two focused working sessions, one on 15 October and one on 19 October, we took the home page to a 91 (grade A) and product pages to 87 (grade B) in our best measured runs.

Disclosure up front: lab scores move from run to run, especially Total Blocking Time. Below I show the best result, the typical range, and what I would tell any client about those numbers.

The starting point: a D grade and a heavy page

The first audit (GTmetrix, Chrome, Amsterdam) showed a page that was visually fine but expensive to run:

  • Home page: performance score 60 (D), Total Blocking Time 699 ms, 382 requests, 4.2 MB transferred, fully loaded in 24 seconds.
  • Product page: GTmetrix score 62 (D), performance 47, Total Blocking Time 2,468 ms, LCP 2.5 s, 387 requests, 4.3 MB, fully loaded in 26.6 seconds.

The root causes were not exotic. They were the usual suspects on a mature Shopify store that has grown over several years: heavy and duplicated JavaScript, tracking and marketing tags loading more than once, images served as CSS backgrounds that the browser could not prioritise, and legacy theme code written before Shopify's modern image tooling existed.

Step 1: Fix how images load

The first session (15 October) was all about images, because they decide when the page looks ready.

  • CSS backgrounds became real images. The hero and reviews sections used background-image, which hides the picture from the browser's preload scanner. I rebuilt them with <img> and <picture>, and the first hero image now loads eagerly with fetchpriority="high".
  • One responsive image snippet, done properly. The theme's image snippet was rewritten around native srcset, sizes and loading="lazy", so the browser picks the right file for each screen instead of a JavaScript lazy-loader deciding after the fact.
  • Legacy image URLs replaced. About 150 old img_url: 'NNNx' calls across 16 theme files were converted to Shopify's current image_url filter, which serves modern formats at the right dimensions.

Result: first-load image weight dropped from roughly 985 KB to 361 KB, and the home page jumped from 70 to the low 80s on the same day.

Step 2: Stop shipping JavaScript nobody needs

With images sorted, the remaining problem was JavaScript, which is what drives Total Blocking Time. Three changes made the biggest difference:

  • jQuery and SweetAlert2 removed from the critical path. Both were loaded on every page for a single back-in-stock modal. jQuery is gone entirely from that flow, and SweetAlert2 is now loaded only when a customer actually opens the modal.
  • Duplicate cross-sell code removed. The product page was running two cross-sell implementations at once, and one of them threw a crossSellSettings already declared error on every visit. I removed the duplicate, disabled the redundant app embed, and verified that the cart-drawer cross-sell still works.
  • Tracking consolidated. Google Tag Manager was loaded from more than one place, and PostHog was installed directly in the theme. The theme-level code is gone, tags now run through Shopify's Customer Events, and the duplicate loaders were switched off.

Step 3: Rebuild the product page gallery

The product gallery and lightbox were one of the heaviest parts of the product page. I rewrote the gallery markup and logic, fixed the lightbox and pickup-drawer stacking issues that showed up along the way, and added a preload hint for the main product image so the Largest Contentful Paint element starts downloading as early as possible.

I also gave the product recommendations block a skeleton placeholder with a reserved height. Content arrives later, but the layout never jumps: product page Cumulative Layout Shift sits at roughly 0.0001.

The results

Same tool, same location (GTmetrix, Chrome, Amsterdam), before versus our best run after the second session:

Metric Home: before Home: after Product page: before Product page: after
Performance score 60 (D) 91 (A) 47 86
GTmetrix score 70 91 (A) 62 (D) 87 (B)
Total Blocking Time 699 ms 92 ms 2,468 ms 316 ms
Largest Contentful Paint 2.03 s 1.49 s 2.53 s 0.84 s
Fully loaded 24.2 s 8.1 s 26.6 s 8.8 s
Requests 382 299 387 357
Page weight 4.2 MB 2.7 MB 4.3 MB 3.0 MB

The headline numbers: Total Blocking Time down by roughly 87% on the home page and 87% on the product page, fully loaded time cut by about two thirds, and roughly a third less data transferred.

An honest note on lab scores

I re-tested both pages the day after the final changes and got an 81 (grade B) on each. That is normal. Lab tests run on shared infrastructure, and Total Blocking Time in particular swings from run to run. On the afternoon of 19 October alone, the home page scored 89, 85 and 91 across three runs. What matters is the direction and the range: the site went from a D to a stable B with A-grade runs, and the underlying improvements (less JavaScript, lighter images, stable layout) are what real visitors feel, whatever a single test says.

What is still on the list

The remaining weight is mostly third-party: marketing and analytics scripts and a large search app. These are business decisions as much as technical ones, so the next step is an app audit with the SuperBra team, deciding what each script earns. A few smaller items are queued as well: trimming how early the product recommendations load, and removing a cross-sell block that currently loads scripts but renders nothing.

Key takeaways

  • Start with what the user sees. Fixing image loading first gave the biggest visible win for the least risk.
  • Audit scripts before adding code. Most of the gain came from removing duplicated or unnecessary JavaScript, not from clever new code.
  • Work on a duplicate theme and test before publishing. Every change here was verified on a duplicate theme, with the old theme kept as an instant rollback.
  • Report ranges, not single scores. A good case study shows the before, the best run and the typical run.

Want the same for your store? If your Shopify site feels slower than it should, book a call and I will run a performance audit and show you where the biggest wins are.