WordPress async JS and CSS loading
Page speed optimizations are a constant battle. New features / components are added to a website, but often there is no time for performance improvements. One of the most important factors regarding page speed load time is eliminating blocking resources. CSS/JS files prevent DOM from rendering. Until these assets are downloaded, the page will remain blank.
Our goal is to show our visitors page content as fast as possible. The most important content is above-the-fold (viewport that is visible on initial load). The assets responsible for this aspect should be prioritized to load.
WordPress scripts and styles
Sophisticated systems often use conditional assets loading, or even critical CSS generation. However, WordPress uses simpler architecture, where most assets are loaded globally. In most cases, WP uses a ready-to-use theme and multiple plugins that are enqueuing their CSS styles and javascripts. Our goal here is simple, without modifying the existing code we want to make assets load asynchronously.
Async JavaScript settings
For JavaScripts, the most convenient way will be to use the plugin Async JavaScript by Frank Goossens. He is also the author of the popular ‘Autoptimize’ plugin.
The following settings should be optimal for most WordPress websites:
Wp-admin / Settings / Async JavaScript
– Enable Async JavaScript – checked
– Apply Defer (jQuery excluded)
– Script Exclusion: wp-includes/js/dist/dom-ready.min.js, wp-includes/js/dist/hooks.min.js, wp-includes/js/dist/i18n.min.js
Now ‘Save settings’ and check your website using the Incognito Mode (to prevent Browser Cache). For troubleshooting, check the Browser Console red javascript errors. Determine the js file name that causes the error and add it to Exclusions in plugin settings.
Asynchronous CSS loading
Other resources that can block page rendering are styles. The “Async CSS loading hack” solution, which has full browsers support, is to modify link stylesheet tag by changing media to “print” and by adding an onload inline function.
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">
Now, how to achieve this in WordPress? By default, styles in WordPress are added by using the wp_enqueue_style built-in function. Your theme should already have a similar action defined:
/** * * Enqueue scripts and styles. */ function ct_load_scripts() { define( "CT_VER", "5" ); wp_enqueue_style( 'ct-theme-style', get_template_directory_uri() . '/assets/css/style.css', [], CT_VER ); } add_action( 'wp_enqueue_scripts', 'ct_load_scripts' );
How to Load CSS Asynchronously in WP
To make it load in an async-way, we’re going to use the style_loader_tag filter and modify link tags on the fly. In addition, the preload tag will be generated to fetch resources earlier.
/** * WP - Load CSS Asynchronously * Eliminate blocking-resources */ function ct_style_loader_tag($html, $handle) { $async_loading = array( 'u1_theme-style' ); if( in_array($handle, $async_loading) ) { $async_html = str_replace("rel='stylesheet'", "rel='preload' as='style'", $html); $async_html .= str_replace( 'media=\'all\'', 'media="print" onload="this.media=\'all\'"', $html ); return $async_html; } return $html; } add_filter('style_loader_tag', 'ct_style_loader_tag', 10, 2);
Pros of async loading
Our solutions change assets’ tags “on-the-fly”. Proper defer, preload or onload parameters are added to script and link resources. Contrary to other solutions, there is no need for the generation of new files, thinking about server permissions or clearing assets’ cache. This should work even in the load-balancer configuration where there are multiple independent instances of servers with WordPress code. Changes in the plugins / new js files added? These shouldn’t be an issue.
Preloader opacity:0
Now Javascripts aren’t blocking page rendering. That’s good, this should result in faster page load. The downside may be that for a split second unstyled page content could potentially be visible to a visitor (CSS not loaded yet, but HTML already fetched). Inline Head CSS to the rescue! We will hide body content by default, using opacity:0.
// header.php <head> <style> body { opacity:0; } </style> </head>
Then – in our asynchronously loaded style.css file, the opacity will be set to 1 again. The result: after the loading of the CSS file, styled content will be revealed to the user.
// style.css body{ opacity:1 }
That’s it for today’s tutorial. Make sure to follow us for other useful tips and guidelines. Also you can check our article about fast tips for WordPress speed.