Language: Nederlands · English
While optimizing a WooCommerce store, we ran into something unexpected: product listings and category pages had suddenly become much heavier than expected.
Not because of larger images.
Not because of extra CSS.
Not because of a slow server.
But because of inline JavaScript state that WooCommerce places directly inside the first HTML response of the page.
On some category pages, we saw more than 300KB of extra HTML. That is significant, especially because this happens before the browser even starts downloading external scripts, stylesheets, or images.
After further investigation, the difference turned out to be reproducible between WooCommerce 10.7.0 and WooCommerce 10.8.0.
The short version
Starting with WooCommerce 10.8.0, the modern Product Collection / Product Template block appears to load full product data for every visible product into the WordPress Interactivity API state.
That data ends up in:
wp-script-module-data-@wordpress/interactivity
And more specifically inside:
state.woocommerce/products.products
As a result, a category page no longer contains only the visible product cards. It also contains large JSON objects with product data, including prices, descriptions, stock status, categories, add-to-cart data, images, gallery images, and responsive image metadata.
For a few products, that may still be manageable. But on shop and category pages with multiple products, this can quickly add hundreds of kilobytes of extra HTML.
What changed?
The relevant change appears to be in WooCommerce PR #63662:
Refactor iAPI blocks to read product in context
In WooCommerce 10.7.0, the Product Collection block already used the modern block structure, but the shared woocommerce/products state did not yet contain full product objects for all displayed products.
Starting with WooCommerce 10.8.0, ProductTemplate.php calls this function for every product in the product loop:
wc_interactivity_api_load_product(
'I acknowledge that using experimental APIs means my theme or plugin will inevitably break in the next version of WooCommerce',
$product_id
);
That function loads product data into the shared Interactivity API store.
Technically, this is understandable. WooCommerce is increasingly moving toward interactive blocks, shared frontend state, and more modern client-side interaction.
But for product listings, that choice has a clear downside: the initial HTML response becomes significantly larger.
Our test
To verify this properly, we set up a clean WordPress installation with WooCommerce 10.7.0.
We created test products with, among other things:
- product images
- gallery images
- descriptions
- short descriptions
- prices
- stock status
- attributes
- one variable product
We then measured the same pages, updated WooCommerce to 10.8.0, and measured again.
| Page | WooCommerce 10.7.0 | WooCommerce 10.8.0 |
|---|---|---|
/shop/ |
139,967 bytes | 317,364 bytes |
/product-category/laptops/ |
140,182 bytes | 317,899 bytes |
| Variable product page | 146,492 bytes | 213,799 bytes |
The inline Interactivity API state on the shop and category pages grew from roughly 1.4KB to around 179KB.
On a real product catalog, this can become even heavier. In our live environment, we saw WooCommerce pages where the Interactivity API state was around 275KB to 387KB.
That is only the inline state. The rest of the page, scripts, stylesheets, and images still come on top of that.
Why does this become so large?
WooCommerce does not inline the actual image files into the HTML. So the problem is not the JPG, PNG, or WebP files themselves.
The problem is metadata.
A product object contains much more than just a title and a price. For example:
- product name
- slug
- permalink
- SKU
- price data
- price HTML
- short description
- full description
- categories
- tags
- attributes
- stock status
- add-to-cart data
- image metadata
- gallery images
- responsive image sizes
- srcsets
Image data in particular can grow quickly. WordPress often generates multiple image sizes for each image. If a product has multiple gallery images, that can produce a lot of metadata.
For products such as laptops, desktops, components, and accessories, there are often many specifications and attributes as well.
So the HTML becomes heavier before the browser even starts loading the rest of the page.
Why this matters
HTML size matters.
A heavier initial HTML response can affect:
- Time to First Byte
- document download time
- HTML parsing
- browser memory usage
- mobile performance
- cache efficiency
- Core Web Vitals
- crawlers visiting many category pages
For small webshops, an extra 100KB or 200KB may not sound dramatic. But category pages are often exactly the pages that receive a lot of traffic. They are visited by users, search engines, filters, internal links, and sometimes advertising campaigns.
If every category page contains hundreds of kilobytes of unnecessary extra HTML, you pay that cost again and again.
That is exactly why, when we work on websites and webshops, we do not only look at how a page looks. We also look at what happens under the hood. A webshop can look visually polished and still be unnecessarily heavy from a technical point of view.
And because this data is inline in the document, you cannot simply solve it with defer, async, or better image compression. The bytes are already inside the HTML itself.
Is this a bug?
That depends on your definition.
The architecture appears to be intentional. WooCommerce is moving toward modern block interaction through the WordPress Interactivity API. This allows product blocks to share state with each other. That is useful for dynamic product collections, filters, add-to-cart interaction, variations, and client-side navigation.
But the amount of data loaded upfront seems problematic.
A category page usually does not need full Store API-like product objects for every visible product. For a product card, the following data is often enough:
- product name
- product URL
- price
- primary image
- stock or purchasability status
- add-to-cart information
Long descriptions, full galleries, extensive attributes, all responsive image metadata, and complete product objects are usually not needed in the first HTML response of a category page.
That is why we prefer to call this a performance regression rather than simply a bug.
The functionality is understandable.
The amount of data is debatable.
Variable products can be even more sensitive
Variable products make this even more interesting.
WooCommerce also has a newer add-to-cart-with-options route. For variable products, it can make sense that the frontend needs more information. After all, the browser has to know which variation belongs to which selected options, which price applies, whether the variation is in stock, and which add-to-cart data is required.
But here too, the difference lies in how much data is loaded upfront.
For a variable product with many variations, fully hydrating variation objects can quickly become heavy, especially when variations have their own images, SKUs, stock statuses, descriptions, or metadata.
For a single product page, that may sometimes be defensible.
For a category page with many products, it becomes problematic much faster.
How to measure this yourself
You can check this fairly easily on your own site.
For example, download the HTML of a category page:
curl -s https://yourdomain.com/shop/ -o shop.html
Then check the size of the HTML:
du -h shop.html
Next, search for the Interactivity API state:
grep -o "wp-script-module-data-@wordpress/interactivity" shop.html | wc -l
Or search specifically for WooCommerce product state:
grep -o "woocommerce/products" shop.html | wc -l
If you want to inspect it more precisely, look in the HTML for:
wp-script-module-data-@wordpress/interactivity
And inside that JSON for:
state.woocommerce/products.products
If you see large objects for every visible product there, you are probably seeing the same behavior.
What can you do about it?
There are roughly three options.
1. Accept it
If your catalog is small, your caching is configured well, and your category pages are still fast enough, you can leave it as it is.
You then benefit as much as possible from WooCommerce’s modern block architecture and do not have to maintain custom templates.
For small shops or pages with only a few products, that may be perfectly fine.
2. Wait for WooCommerce optimizations
WooCommerce could improve this by hydrating a smaller product shape on product archives.
For example:
- only load data that visible blocks actually need
- load heavier product data only when interaction requires it
- do not include gallery data by default in archive views
- do not inline descriptions and extensive attributes on category pages
- load variation data only when the user selects options
That way, WooCommerce could keep the benefits of modern interactive blocks without making the first HTML response unnecessarily heavy.
3. Use server-rendered WooCommerce templates
For many webshops, this is probably the most practical route.
A classic or custom server-rendered product loop can still work very well with:
- product cards
- sorting
- pagination
- prices
- stock labels
- add-to-cart buttons
- SEO-friendly markup
But without placing full product objects inline in the HTML.
For SEO, performance, and predictability, that is often a better trade-off than a heavier app-like category page.
That does not mean modern WooCommerce blocks are bad. It does mean that, for larger catalogs, you should measure what they do to your HTML output.
When it comes to webshop development, this is exactly the kind of decision that makes a difference: not just installing a plugin and hoping it is fast enough, but deliberately choosing the technology that fits the content, the number of products, and visitor behavior.
Our conclusion
WooCommerce 10.8.0 introduces a clear HTML size regression for product listings that use modern Product Collection blocks.
The change appears to come from a deliberate architectural direction: shared product state through the WordPress Interactivity API. That is technically interesting and can be functionally valuable.
But in its current form, that state can contain much more data than a category page needs.
For webshops with product categories, many product images, many attributes, or variable products, this is absolutely worth measuring.
We opened an issue for this in WooCommerce:
Hopefully this leads to an optimization where WooCommerce keeps the benefits of modern interactive blocks, while making the first HTML response leaner again.
Modern frontend interaction is great.
But not if every category page has to ship hundreds of extra kilobytes of HTML for it.
Do not let your webshop become unnecessarily heavy
A fast webshop does not start with one cache plugin or one hosting checkbox. It starts with measuring, understanding, and then improving the right things.
Sometimes the gain is in better hosting. Sometimes in caching. Sometimes in images. And sometimes, as in this case, in the way WooCommerce itself builds the page.
At Forcys, we help businesses build fast, stable, and practical websites and webshops. We do not only look at the front end, but also at performance, maintainability, SEO, and the technical choices behind the site.
Want to know whether your WordPress or WooCommerce site is unnecessarily slow or heavy? Contact us via forcys.nl/contact. We will be happy to take a look.