Skip to content
What To Fix First

How to stop plugins loading on every page

WordPress loads every plugin's scripts and styles on every page by default. How to find which ones a page doesn't use, dequeue them with a few lines of code, or do it per page with a script manager.

A grid of three plugins against three pages. By default every plugin loads its files on every page; the accent marks show the only page where each plugin is actually used — one cell per row, the rest is wasted weight.homecontactarticlesliderform plugintable pluginloadseverywhere■ used on this page▨ loaded, never used
This diagram is free to reuse with credit — all nineteen, as SVG or PNG.

What is happening

Every plugin that puts something on the front end registers its scripts and stylesheets with WordPress, and WordPress prints them into the page. The default is to print them on every page. A site with a slider on the home page, a form on the contact page and a table on one article loads all three plugins’ files on every page — including pages that use none of them. Multiply by a typical fifteen front-end plugins and you have most of what “WordPress is slow” means.

Run the plugin checker on two or three different pages. It ranks each plugin by weight and flags the ones with no trace in the page’s markup — those are your candidates.

Step 1 — see the handles

Install Query Monitor (free), open a page as a logged-in admin, and read the Scripts and Styles panels: every file with its handle, source and position. Note the handles that belong to plugins the page does not use.

Step 2 — dequeue conditionally

Put this in a small must-use plugin (wp-content/mu-plugins/dequeue.php) or a child theme’s functions.php. Priority 100 runs after the plugins enqueued their files, so the dequeue actually happens.

<?php
add_action( 'wp_enqueue_scripts', function () {
    // Contact Form 7: only where a form is.
    if ( ! is_page( 'contact' ) ) {
        wp_dequeue_style( 'contact-form-7' );
        wp_dequeue_script( 'contact-form-7' );
    }
    // Slider: only on the front page.
    if ( ! is_front_page() ) {
        wp_dequeue_style( 'rs-plugin-settings' );
        wp_dequeue_script( 'revmin' );
    }
    // A table plugin: only where the shortcode appears.
    if ( is_singular() && ! has_shortcode( get_post()->post_content, 'table' ) ) {
        wp_dequeue_style( 'tablepress-default' );
    }
}, 100 );

The conditionals are WordPress’s own: is_front_page(), is_page(), is_singular(), is_product() from WooCommerce, and has_shortcode() or has_block() to detect usage from the content itself. Test each page you excluded and each page you kept.

Step 3 — the files you must keep: defer them

Scripts a page does use still need not block the first paint. Add defer to everything except inline-dependent jQuery:

add_filter( 'script_loader_tag', function ( $tag, $handle ) {
    if ( in_array( $handle, [ 'jquery-core', 'jquery-migrate' ], true ) ) return $tag;
    return str_replace( ' src=', ' defer src=', $tag );
}, 10, 2 );

If something on a page stops working after this, it has an inline script that expects a deferred file to have run already; either exclude that handle or move the inline code to a DOMContentLoaded listener.

The specific offenders the checker flags

  • WooCommerce cart fragments on non-shop pages: wp_dequeue_script( 'wc-cart-fragments' ) unless is_woocommerce() || is_cart() || is_checkout().
  • The emoji script: remove_action( 'wp_head', 'print_emoji_detection_script', 7 ) and the matching wp_print_styles removal.
  • reCAPTCHA on pages without a form — Contact Form 7 has a documented filter to limit it; other form plugins have a setting.
  • Font Awesome — replace the handful of icons a page uses with inline SVG and dequeue the set.

Everything above is free and permanent: a dozen lines in a must-use plugin, tested page by page. If you would rather tick boxes than maintain conditionals — or the site has fifty plugins and a client who will install more — a script manager shows every handle per page with an on/off switch and a defer/delay option. For that case we use Perfmatters. That is an affiliate link: we earn a commission if you sign up, at no extra cost to you.

Check it worked

Re-run the plugin checker on the same pages: the flagged plugins should disappear from pages that do not use them, and the render-blocking count should drop. Then run the Core Web Vitals check to see how much time it recovered — weight removed from the render-blocking path shows up directly in the LCP timeline.

Common questions

Why do plugins load on pages that don't use them?
Because WordPress gives a plugin no reliable way to know, at the moment it registers its files, whether the page about to render contains its shortcode or block. The safe default for a plugin author is to load everywhere. Good plugins check for their own shortcode first; many do not.
Will dequeuing break the plugin?
Only on a page that actually uses it — which is why you dequeue conditionally, not globally. If a page renders wrong after the change, that page uses the plugin and the condition needs to include it. Nothing is deleted; the plugin still works everywhere it loads.
Where do I find the handle names?
The plugin checker lists each file's URL; the handle is what the plugin passed to wp_enqueue_script or wp_enqueue_style, and it is usually the file name without the extension. The Query Monitor plugin's Scripts and Styles panels show the exact handles per page, which is the reliable way.
Is a caching plugin enough?
No. Caching serves the page faster; it does not change what is on it. A cached page still ships every plugin's CSS and JavaScript. Caching fixes the server phase; this fixes the download and render phases. You want both.

Check a page against this

Free, no signup, no ads. We keep nothing except the shareable result, for 30 days.

Enter any public URL. You’ll get the one change that recovers the most load time, what it’s worth, and the measurements underneath.

Other guides