We are a big fan of the WooCommerce plugin for its stability and the ability to create our own custom templates. We are also a big fan of clean UX and performant enterprise level websites.
One thing we have never been a fan of was WooCommerce Blocks. Don’t get me wrong, the blocks are really cool. In a world of Full Site Editing it’s reasonably necessary for WooCommerce to provide blocks for users to have the ability to build the site code free. Assuming you are working on a single site and don’t need customization, I say, “Go for it.”
Well, you’re reading this post so I assume you are more like us. The blocks fail in situations like:
- Large multisite networks.
- Customizations.
- Heavy traffic or low resource servers.
Large multisite networks
Blocks are great when you only need to set them up once. When you need to configure 50 sites on your network and add the blocks one at a time, it will be substantially more work to setup than rolling out a theme template. Not to mention doing maintenance is nearly impossible.
Full Site Editing tries to make things easier by introducing reusable template parts so you can use the same blocks in multiple areas (kind of like widgets). Even so, the template parts are still only available in one site and you have to copy/paste to other sites.
We are internally working on a system to sync template and template parts across all sites in linked networks but it is not ready for prime time yet.
Customizations
Have you tried to customize a block yet? Good luck. At best you are going to end up with several filters hacking parts not really intended to be touched. At worst you are going to be writing awkward comment attribute HTML markup.
Again, rolling out a PHP template is not only easier but has full support for PHP throughout.
Heavy traffic or low resource servers
This point is actually what prompted this solution for us. This week we rolled out version 7.2.3 of WooCommerce onto the site you are currently on. To our dismay, we noticed our average response time went from roughly 275ms to 338ms. That may not sound like much but our site processes millions of requests each month which adds up to a lot of extra CPU time.
Tracing the CPU process we noticed a ton of access
calls to files which look like this.
access("/public_html/content/plugins/woocommerce/packages/woocommerce-blocks/build/product-summary.asset.php", F_OK) = -1 ENOENT (No such file or directory)
access("/public_html/content/plugins/woocommerce/packages/woocommerce-blocks/build/product-summary.asset.php", F_OK) = -1 ENOENT (No such file or directory)
access("/public_html/content/plugins/woocommerce/packages/woocommerce-blocks/build/product-summary-frontend.asset.php", F_OK) = -1 ENOENT (No such file or directory)
access("/public_html/content/plugins/woocommerce/packages/woocommerce-blocks/build/product-summary-frontend.asset.php", F_OK) = -1 ENOENT (No such file or directory)
access("/public_html/content/plugins/woocommerce/packages/woocommerce-blocks/build/product-summary.asset.php", F_OK) = -1 ENOENT (No such file or directory)
Well that’s strange, we are not using any WooCommerce Blocks. So we did some more digging. Turns out, the woocommerce-blocks
directory alone accounted for roughly 1/3 or our entire server’s CPU usage. Pretty surprising for a feature we are not even using.
Solution
As of WooCommerce 8.6 the blocks package has been merged into the core plugin and is no longer available to be removed as described below. At this time, the only path forward is to prevent the blocks from being registered.
Edit: 2024-05-01
For WooCommerce version 8.6+
- Use the
woocommerce_blocks_loaded
hook to wait for the plugin to be loaded. - Use the
Package
class to get the container which holds the block registering class. - Remove the action from
init
which registers the WooCommerce blocks. - Unregister the global
wc-block-style
resource.
For WooCommerce before version 8.6
There are many articles which explain how to remove WooCommerce blocks from the Gutenberg block inserter. And how to dequeue the unused stylesheets from the front end of your site. Do a quick search and you’ll find plenty. All work fine for their purposes.
We were using some of the known solutions ourselves until we discovered the latest performance issue.
Hiding things from the admin solves the UX issue but it does nothing to reduce the performance hit.
WooCommerce does not provide a way to remove the feature via settings nor WordPress hooks. Luckily for us, the woocommerce-blocks directory is treated as a “package” internally and we can use a little PHP magic to get things done.
- On line 4 we tap into the action the woocommerce-blocks is loaded on firing before it is loaded by using priority 6 on line 15.
- On line 12 we create an anonymous PHP class which extends the class the woocommerce uses to load its internal packages.
- On line 19 we remove the ‘woocommerce-blocks’ package from the list to load.
These few steps give us access to the protected $packages
property of an otherwise inaccessible class.
- Blocks are not registered.
- Stylesheets and JavaScript are not loaded.
- Plugin overhead is mitigated.
Implementation Notes
You can see from the code, the closure must fire on the plugins_loaded
hook. Since the plugins_loaded
hook fires before themes are loaded, this code must go within a plugin.
A convenient way to use it:
- Create a custom PHP file named something like
disable-woocommerce-block.php
. - Add above example code in the file.
- Put the file in the
wp-content/mu-plugins
directory.