How To Minimize Main-Thread Work In WordPress By Reducing Long CSS/JS Tasks

Minimize main thread work wordpress

In most WordPress cases, minimizing main-thread work involves reducing (and optimizing) CSS/JavaScript, including third-party code and jQuery.

PSI tells you whether the main-thread is blocked by CSS/JavaScript or other tasks, but I recommend the Chrome Dev Tools coverage report to see CSS/JS files taking longest to load.

In WordPress, the main-thread is commonly blocked by bloated tools (themes, plugins, and page builders that add CSS/JS) as well as third-party JavaScript. If you’re not able to remove these, you can try hosting third-party JavaScript locally or delaying it, activating built-in page builder optimizations, and using Perfmatters to remove unused CSS and unload unused assets.

While there are other optimizations that can help, I recommend tackling this at the source by making sure you’re on a lightweight setup. Otherwise, there are more files you have to optimize.

For best results, we’ll be using Perfmatters for the script manager, removing unused CSS, finding jQuery-dependent plugins, optimizing fonts/analytics, lazy loading CSS background images, and other optimizations which help minimize main-thread work.

 

1. Find Your Longest Tasks

The diagnostics section of PSI shows “avoid long main-thread tasks.” However, it doesn’t show which specific files are blocking the main-thread. That’s why I recommend the coverage report of Chrome Dev Tools which shows your largest CSS/JavaScript files, their total bytes, and usage.

Css javascript chrome dev tools

 

2. Avoid Bloated Themes, Page Builders, Plugins

Elementor, Divi, and Avada add lots of CSS/JS which can flag several PSI items. This is a big reason page builders got crushed during web vitals and started taking speed more seriously.

While it’s best to go with lightweight alternatives like GeneratePress/Kadence, ditching your page builder may not be on the list. Here are a few things you can do to optimize page builders:

  • Active Elementor Experiments or Divi Performance settings.
  • Limit the number of Elementor columns/widgets (see this video).
  • Code your header, footer, and sidebar in CSS (don’t use page builders).
  • Don’t go crazy with adding page builder plugins – it’s a recipe for disaster.
  • Elementor and host fonts locally and preload them in the performance settings.

Fastest wordpress themes

 

3. Activate Built-In Page Builder Optimizations

Elementor and Divi both have built-in optimization settings that help reduce CSS/JavaScript. Here’s a test I did on an Astra Starter Site with Elementor’s Experiments enabled vs. disabled:

Elementor with without experiments font optimization

 

If you must use a page builder, code these in CSS.

You can use page builders to create pages, but these appear across your site. CSS is less bloated than page builder code and this was the first thing WP Johnny did when I hired him to remove Elementor, which dropped mentions of “Elementor” in my source code from about 2,000 to 200.

Makes a big difference!

Elementor source code

 

5. Unload CSS/JavaScript

I use the Perfmatters script manager, but Asset CleanUp is fine too.

Once the script manager is activated in the settings, view any page/post on your site and find the script manager. It will show you all CSS/JavaScript files loading on that page. Sometimes, plugins load across your entire site even when they’re not being used on specific pages, which means you can safely disable them where they’re not used. Make sure to enable test mode to prevent things from breaking your site while testing this out. Here are a few common examples:

  • Disable social sharing plugin everywhere but posts.
  • Disable contact form plugin everywhere but contact page.
  • Disable page builder plugins everywhere except current URL(s).
  • Disable page builder plugins everywhere except current URL(s).

Disable plugins perfmatters

 

6. Remove jQuery-Dependent Plugins

If you’re using a lot of jQuery-dependent plugins, it can be the longest main-thread task:

Avoid long main thread tasks 1

To find which plugins use jQuery, select display dependencies in the script manager settings of Perfmatters.

Perfmatters display dependencies jquery

Now when you go to your script manager, you will “jQuery” and all plugins requiring it. This is another reason I don’t recommend page builder plugins, because look at how many use jQuery:

Jquery plugin dependencies 1

 

7. Remove Unused CSS (But Not In WP Rocket)

Perfmatters, FlyingPress, and LiteSpeed Cache are more effective at “removing unused CSS” than WP Rocket.

While the first 3 plugins load used CSS in a separate file, WP Rocket loads it inline. So not only can it not be cached, but it increases the size of HTML. As the Perfmatters documentation says, the “inline” method is better for scores, but the “separate file” method is faster for actual users.

When I pointed this out to WP Rocket, they insisted inline was better even though every other expert says otherwise, including Vikas Sharma who you probably know from Facebook Groups:

Wp rocket used css

 

8. Use Local Fonts, Analytics, YouTube Thumbnails

Third-party code is one of the biggest culprits of main-thread blocking time, especially when you’re using lots of third-party tracking tools like Google Analytics, Tag Manager, and Heatmaps.

Main thread blocking time 1

Luckily, we can host fonts, Google Analytics, and YouTube thumbnails locally.

  • Google Fonts – instead of pulling fonts from fonts.gstatic.com, host them locally using plugins like Elementor, Perfmatters, FlyingPress, and OMGF. It’s also better for GDPR compliance. On a side note, make sure to test preloading fonts loading above the fold or located in CSS, use font-display: swap (or optional), and woff2.
  • Google Analytics – Perfmatters and Flying Analytics are great for this. Not only can they host Google Analytics locally, but they allow a smaller tracking code and can disable remarketing features which eliminates a 2nd request to DoubleClick.
  • YouTube – FlyingPress is the only plugin I know that hosts YouTube thumbnails locally using a placeholder which eliminates requests to i.ytimg.com. Of course, you should also lazy load videos and replace their iframes with a preview image.

 

9. Delay Remaining Third-Party JavaScript

Once you’ve removed unnecessary third-party code and hosted files locally, you should be able to delay the rest if it loads below the fold. This is the benefit of pushing third-party code down on the page (like ads and social sharing plugins) since delaying it makes your page much faster.

Most (premium) cache plugins do this nowadays, but SiteGround Optimizer and most cache plugins don’t, in which case, use Flying Scripts.

Whichever plugin you use to delay JS, check their documentation on how to add them as well as my list of common JS files to delay. WP Rocket does it automatically, LiteSpeed Cache does this with their “localize resources” settings, and Perfmatters + FlyingPress make you add files manually but allow for more control for things like the timeout period, which I usually set to 5s.

Perfmatters delay javascript

 

10. Remove Gutenberg CSS If You Don’t Use It

If you don’t use Gutenberg blocks, you can dequeue the block library (otherwise block-library/style.min.css loads across your site). Add this to functions.php or with Code Snippets.

<?php
// Fully Disable Gutenberg editor.
add_filter('use_block_editor_for_post_type', '__return_false', 10);
// Don't load Gutenberg-related stylesheets.
add_action( 'wp_enqueue_scripts', 'remove_block_css', 100 );
function remove_block_css() {
wp_dequeue_style( 'wp-block-library' ); // Wordpress core
wp_dequeue_style( 'wp-block-library-theme' ); // Wordpress core
wp_dequeue_style( 'wc-block-style' ); // WooCommerce
wp_dequeue_style( 'storefront-gutenberg-blocks' ); // Storefront theme
}

Gutenberg css
 

11. Lazy Load Background Images

Since page builders (like Elementor) load background images from CSS, they’re not lazy loaded by default which can significantly increase the page size.

If you’re already using Perfmatters, it can lazy load CSS background images. If you’re not, some cache plugins have a lazy-bg or skip-lazy class you can add to background images (which one you use depends if they load in above the fold vs. below). Optimole has similar settings as well.

Perfmatters lazy load css background images

 

12. Reconsider Animations

Google says:

“If any animation triggers paint, layout, or both, the “main thread” will be required to do work. This is true for both CSS & JavaScript-based animations… see CSS Triggers.”

Css transform translate elementor
Layout shifts can avoided with CSS transform: translate()

 

13. Disable Icons Or Use Custom Icons

Font Awesome and Elementor’s Eicons add more CSS. You can disable them (use the code below to disable Eicons), or disable them and use custom icons in Elementor → Custom Icons.

add_action( 'wp_enqueue_scripts', 'remove_default_stylesheet', 20 ); 
function remove_default_stylesheet() { 
	wp_deregister_style( 'elementor-icons' ); 
}

Elementor custom icons

 

14. Minify CSS + JavaScript

Minifying CSS/JS strips unnecessary characters, reducing files sizes and main-thread work.

Combining them isn’t usually recommended. WP Johnny explains whether or not to combine CSS/JS but basically, you should only combine if your site has a very small amount – like 10KB.

Minify javascript

 

15. Defer Non-Critical CSS + JavaScript

Deferring CSS and JavaScript can eliminate render-blocking resources.

WP Rocket and other cache plugins usually have a ‘load JavaScript deferred’ option. If this doesn’t give you great results, try Autoptimize along with Async JavaScript. For me, this gave me better results than when I used WP Rocket. Make sure you “apply defer” in Async JavaScript.

Async javascript

 

16. Reduce Memory Usage

Reducing CPU/memory usage lets your server spend more effort on the main-thread and less work on unnecessary tasks.

This is common with shared hosting and as an example, there are tons of people in Facebook Groups who posted how they left SiteGround (one of the worst) and instantly fixed CPU issues. Login to your hosting dashboard, check CPU usage, and make sure it’s nowhere close to 100%.

Siteground cpu limits joke

Cpu usage graph

  • Remove high CPU plugins.
  • Disable Heartbeat + XML-RPC.
  • Increase the autosave interval.
  • Use a CDN to offload resources.
  • Use full page caching if possible.
  • Move and protect the wp-login page.
  • Block bad bots from hitting your site.
  • Replace wp-cron with a real cron job.
  • Use OPcache (Google it for your host).
  • Schedule ongoing database cleanups.
  • Disable usage tracking in plugin settings.
  • Disable or limit preloading in cache plugins.
  • Only preload important sitemap URLs, not the full sitemap.
  • Don’t trigger actions that make your cache plugin clear the entire cache.

 

Frequently Asked Questions

How do I minimize main-thread work in WordPress?

WordPress sites can minimize main-thread work by reducing CSS/JS from bloated themes/plugins (especially jQuery-dependent plugins) and delaying third-party JS.

How do I minimize main-thread work with WP Rocket?

While WP Rocket helps minimize main-thread work through settings like deferring/delaying JavaScript and minification, it can't host fonts locally and the remove unused CSS setting is inferior compared to other cache plugins, as it loads used CSS inline which can't be cached.

How do I minimize main-thread work on mobile?

Coding your header in CSS, unloading CSS/JS on mobile, and simplifying your mobile design with less widgets/columns can help minimize main-thread work on mobile devices.

Cheers,
Tom

You Might Also Like:

5 Comments...

  1. “4. Don’t Use Page Builders For Your Header, Footer, Sidebar – If you must use a page builder, code these in CSS.

    You can use page builders to create pages, but these appear across your site. CSS is less bloated than page builder code and this was the first thing WP Johnny did when I hired him to remove Elementor, which dropped mentions of “Elementor” in my source code from about 2,000 to 200.”

    Is this easy to do and apply to the entire site??

    I have elementor and am having to do all of this diagnosing by myself as a complete newb. I used your suggestion of Siteground + FlyingPress yesterday and it took me from a 26 mobile speed score to a 65-77 score.

    Reply
    • It’s somewhat easy IF you’re a developer… I’m sure you can find a freelancer or someone in a FB group who can do it for much cheaper than Johnny.

      That’s a good start with FlyingPress. If CSS/JS are giving you trouble, are you using anything to unload assets like Asset CleanUp or Perfmatters? This is something SG Optimizer and FlyingPress don’t do.

      Hopefully you’re not paying SiteGround’s renewal rates after the 1 year intro period… $18 – $45/mo for shared hosting is robbery.

      Reply
  2. How to migrate from Elementor to Oxygen without stress or headaches? I look at the bloated Elementor DOM and I am a little shocked. Before, when I didn’t think about the speed of my website, I didn’t pay attention to it.

    By the way, I disagree with your conclusions about cloudways, which you have mentioned very often lately. Upcloud is better. Just test it yourself to be sure.

    Reply
    • I wouldn’t be the person to ask about DIY migration from Elementor to Oxygen. I hired this guy to recreate my site in Oxygen, haven’t launched it yet, still needs work, but he did a great job and was affordable: https://www.facebook.com/gabrieluntura

      I’ve heard great things about UpCloud but have been happy with Cloudways and have no reason to switch for now. I’ll try to run some tests soon.

      Reply

Leave a Comment