Defer JavaScript and CSS Loading in WordPress to Improve Page Speed

Page speed is a primary ranking signal in Google’s Core Web Vitals assessment, and render-blocking JavaScript and CSS are among the most frequent causes of poor Lighthouse scores. WordPress enqueues all registered scripts and stylesheets synchronously by default, which forces the browser to download and parse each resource before it can render the page. Adding the defer attribute to non-critical scripts tells the browser to fetch them in the background and execute only after HTML parsing is complete. WordPress exposes the script_loader_tag filter to modify the HTML output of any enqueued script without touching core files. For stylesheets the style_loader_tag filter provides equivalent control over link element attributes. Deferred scripts still execute in document order, so dependencies between scripts are preserved as long as they share the same defer attribute. The wp_resource_hints filter is a clean way to inject preconnect hints for external origins such as Google Fonts, reducing DNS lookup latency. Removing a blocking Google Fonts stylesheet and replacing it with a resource hint typically shaves 200–400 ms off Time to First Byte on slow connections. Chrome DevTools Performance tab and the Opportunities section of a Lighthouse audit both pinpoint render-blocking resources with per-resource timing data. You can combine deferred scripts with Nginx FastCGI caching and a CDN to push Total Blocking Time below Google’s 200 ms threshold. The database cleanup guide covers a complementary server-side optimisation that reduces query time on every page load. Targeting only scripts that do not block above-the-fold rendering minimises the risk of JavaScript errors caused by premature execution.

Problem: Theme and plugin scripts enqueued without defer block HTML parsing, delaying First Contentful Paint and increasing Total Blocking Time in Core Web Vitals.

Solution: Apply the script_loader_tag filter to append the defer attribute to selected script handles, dequeue the synchronous Google Fonts stylesheet, and register a preconnect hint via wp_resource_hints.

// Add defer to selected script handles
add_filter('script_loader_tag', function($tag, $handle) {
    $defer = ['my-theme-main', 'slick-slider', 'contact-form'];
    if (in_array($handle, $defer, true)) {
        return str_replace(' src=', ' defer src=', $tag);
    }
    return $tag;
}, 10, 2);

// Dequeue blocking Google Fonts stylesheet
add_action('wp_enqueue_scripts', function() {
    wp_dequeue_style('google-fonts');
}, 100);

// Add preconnect hints for Google Fonts origins
add_filter('wp_resource_hints', function($hints, $relation_type) {
    if ($relation_type === 'preconnect') {
        $hints[] = ['href' => 'https://fonts.googleapis.com'];
        $hints[] = ['href' => 'https://fonts.gstatic.com', 'crossorigin' => 'anonymous'];
    }
    return $hints;
}, 10, 2);

NOTE: Replace the handle names in the $defer array with the actual handles registered by your theme and plugins — check them in the browser DevTools Sources tab or with wp_scripts()->registered.