help1
shopify unused cssshopifypage speedpsi

What's Left in Shopify's Unused CSS Warning After Subsetting

Six months after Shopify's April CSS subsetting change, the shopify unused CSS warning still shows up in PSI. Here is what you can actually fix.

help1 Team
What's Left in Shopify's Unused CSS Warning After Subsetting

Open PageSpeed Insights at pagespeed.web.dev. Type in a Shopify URL. Run it on mobile. Scroll past the three big scores, past Opportunities, into Diagnostics. There it is: Reduce unused CSS, with an estimated saving somewhere between 30KB and 300KB. Click to expand and you get a short list of file names. Some sit on cdn.shopify.com, some on app vendor CDNs, maybe one you cannot place at all. The instinct is to open the theme editor and start deleting. Hold that for a minute.

The shopify unused CSS warning is one of the two PSI line items merchants misread most often. The other is its JavaScript twin, which I wrote about in an earlier walk through the shopify unused javascript warning. The CSS version is harder, because CSS has no defer and no async attribute, so none of the standard web-performance tricks transfer. Then in April 2026, Shopify shipped a platform change that quietly removed a big chunk of the problem and left a smaller, more interesting part behind.

This is the walk I did through the warning on a client's Horizon store last week, in roughly the order I actually did it, including the hypothesis that was wrong.

What I checked first

The top file on my client's PSI list was cdn.shopify.com/s/files/.../styles.css with 180KB flagged as unused. That looked like the obvious target. I opened the theme editor at Online Store > Themes > Edit code, duplicated the theme, and went hunting for the file.

I could not find it.

There is no styles.css in the theme editor's assets/ folder, or in templates/, or in sections/. There is no file to open. For about ten minutes I thought I was looking in the wrong place. I was not. On a modern Shopify theme that follows the sections architecture, styles.css is not a file you write. It is a bundle Shopify's build pipeline creates by concatenating the CSS inside every {% stylesheet %} Liquid tag across every section, block and snippet in the theme. There is no single source file. Horizon has a lot of these tags, which is why the compiled bundle is big.

That alone told me the first-line advice I had seen in a dozen community threads, "find the file and remove the unused rules", was pointing at nothing. There is no file.

The second thing I tried, because every other Shopify Community thread recommends it, was PurifyCSS. The pitch is tidy: scan your HTML, read your CSS, remove rules that match no element. For a static site with a handful of hand-written HTML files, it works.

For a Shopify theme, it does not. Shopify pages are rendered from Liquid templates; the HTML on any one page is a composition of merchant-configured sections, and the sections that appear on the homepage are not the sections that appear on a collection page, a product page, or a blog listing. A rule that looks "unused" on the homepage can be essential on a cart page the tool never scanned. The only way to run these tools correctly is to feed them every rendered permutation of every template, which means knowing in advance every possible configuration your sections can take. Nobody has that.

I ran it anyway on a disposable copy of the theme, just to confirm. It produced a smaller CSS file that broke the product page's variant swatches on first paint. I threw the output away. The 2022-2023 community threads recommending PurifyCSS, UnCSS, and uncss-online are earnest. The advice was copied from static-site playbooks that were never built for templates. Partner replies on Shopify Community still include that advice in 2025. It still does not work.

What April's subsetting quietly fixed

The genuinely interesting thing in this story landed on April 20, 2026, when Shopify rolled out automatic CSS subsetting for {% stylesheet %} tags. There was no admin setting to enable. There was no merchant-facing announcement in the admin itself. The developer changelog went up three days after the change was already live.

What subsetting does: when a page renders, Shopify looks at which sections, blocks and snippets are actually on the page, and includes only the CSS from the {% stylesheet %} tags inside those files. Everything else is left out. The same styles.css URL still exists per page, but its contents are now scoped to what the page actually uses.

For my client's Horizon store, the before-and-after on the compiled CSS payload was real: the global bundle had been 180KB; the per-page version on the product page came in around 95KB. The PSI warning did not vanish, but the kilobyte figure on that row dropped. If the thread you have been reading about styles.css was written before April 2026, it is describing a problem Shopify has partly handled for you. The merchant-side workarounds in those threads, UnCSS and manual pruning and inline critical CSS, are mostly solving a problem the platform solved on its own.

Three caveats on the subsetting change, in the order I ran into them:

  1. It applies only to CSS inside {% stylesheet %} Liquid tags in sections, blocks and snippets. CSS files in the theme's assets/ folder loaded via the stylesheet_tag filter are explicitly exempt and still load globally on every page.
  2. App stylesheets are injected via Shopify's app embed mechanism and also use stylesheet_tag from the app vendor's CDN. They are exempt as well. Every installed app's stylesheet still loads on every page, whether the app's content renders there or not.
  3. The compatibility rule is strict. If one file's {% stylesheet %} block defines a class that an unrelated file's HTML uses, subsetting can drop that class on pages where the defining file does not render. Shopify Theme Check has a ValidScopedCSSClass rule that catches this; most Dawn-descendant themes pass clean, but older or hand-stitched themes do not always.

The post-April composition of the shopify unused CSS warning on a well-structured modern theme has shifted. The theme is doing less of the damage now. Something else is doing most of it.

Where the warning still comes from

Back on my client's PSI list, I filtered Chrome DevTools' Network tab to CSS, reloaded the storefront, and read the hostnames.

Three categories, in rough proportion to the payload:

CategorySourceStill contributing after April 2026?
Theme compiled CSS from {% stylesheet %}cdn.shopify.com/.../styles.cssPartly: now subsetted per page
Asset-folder stylesheetscdn.shopify.com/.../assets/global.css and similarYes, loads globally, exempt from subsetting
App stylesheetsExternal CDNs or app CDNs via stylesheet_tagYes, loads globally, exempt from subsetting

On the Horizon store, the breakdown by weight came out roughly: 95KB subsetted theme CSS, 40KB asset-folder CSS, 170KB app CSS spread across five installed apps. The app bucket was the biggest line item on the PSI diagnostic by a comfortable margin.

The practical implication: for a modern theme after subsetting, PSI's shopify unused CSS warning is mostly describing your installed apps. Reducing the number does not primarily mean editing your theme. It means reconsidering which apps live on every page of your store. That is a different kind of decision, and most of the standard advice does not frame it that way.

The clue I almost missed

Halfway down the stylesheet list in DevTools was a request to a CDN hostname I did not recognise: a review-widget vendor my client had used two years earlier and uninstalled. The app was absent from their installed-apps list. Its stylesheet was still loading on every page view.

I searched theme.liquid for the hostname. There it was: a <link rel="stylesheet"> tag someone on the client's old agency team had pasted directly into the layout, probably when they were debugging a style conflict and never came back to clean up. Uninstalling the app had removed the app embed. It had not touched the manually pasted link.

That one line was 28KB of stylesheet downloaded on every single page view on a store that gets about 40,000 sessions a month. The bytes it saved on the PSI number were small compared to the subsetting improvement. The bytes it saved on real-world bandwidth were larger. More importantly, it was the only piece of the warning I could act on without changing anything about the theme or the current app set.

This is the pattern I now expect on every CSS audit I run. The orphaned stylesheet from a long-dead app is the single actionable slice of the shopify unused CSS warning on a store that already runs a modern Shopify theme. It is a boring piece of hygiene: a text search for rel="stylesheet" in theme.liquid and in your snippets folder, cross-referenced against your current installed apps.

If you find a link tag pointing at a vendor you cannot place, do not assume it is safe to delete. Duplicate the theme first, remove the tag on the copy, publish the copy as a preview, and click through the product, collection, cart and checkout pages before you touch the live theme. If you want a second pair of eyes on a snippet you cannot identify, that is what help1's expert chat is for. We have seen cases where the "orphan" was actually the stylesheet for a free-shipping bar someone had quietly configured into theme.liquid without the app that originally shipped it.

What this diagnostic is actually worth

The last thing I did on this audit was check what the shopify unused CSS reduction had bought my client in Core Web Vitals field data, which is the only speed signal Google actually ranks on.

Google Search Console shows your Core Web Vitals as measured on real users via CrUX, which is what Google uses for ranking signals. PSI's lab-mode diagnostics, including the Reduce unused CSS line, do not feed into that ranking directly. They are a diagnostic hint, not a scorecard. On my client's store, LCP, INP and CLS were already Green in Search Console before the audit. The 95KB-plus-28KB reduction we had just banked did not meaningfully move those field numbers, because the CSS was already arriving in time for first paint.

A merchant on the Shopify subreddit I came across while writing this put it plainly: "I'm not sure if it is even a metric that should be tracked. We run a store which in the 50-60 range and get conversions ranging between 3-3.5%, which is above average for our category." Another in the same thread said web developers treat the lab score as pass/fail against Core Web Vitals and otherwise ignore it. Neither of those is universal advice, a store that is red in CrUX has a real problem to fix, but both describe the shape of the trap. The PSI number can get better while the field data doesn't move, and the field data can be fine while the PSI number stays middling.

So on this audit: subsetting did its work for free in April. We removed one orphaned link tag. We left the theme's compiled bundle alone. We left the asset-folder CSS alone. We did not touch the app stylesheets, because the apps were paying for themselves. The remaining shopify unused CSS warning sat at a lower kilobyte figure than before, still non-zero, and the field data was green. That is the honest shape of a well-tended Shopify store in late 2026.

The shopify unused CSS warning reads like a to-do item, and on a modern theme in late 2026 it is mostly a weather report about which apps you run. Most days the right response is to glance at it, note which category each line belongs to, and get back to the work that actually moves conversions.

Still stuck? Talk to an expert.

Our vetted Shopify experts can fix this issue for you in a live session. $39 per session. Your first 15 minutes are free.