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.
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' )unlessis_woocommerce() || is_cart() || is_checkout(). - The emoji script:
remove_action( 'wp_head', 'print_emoji_detection_script', 7 )and the matchingwp_print_stylesremoval. - 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
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
- How to fix a slow LCP — Your main image or headline takes too long to appear.
- How to fix layout shift — Content jumps around while the page loads.
- How to fix slow INP — Taps and clicks take a moment to do anything.
- How to fix a slow server response — Your server is slow to start replying at all.
- How to eliminate render-blocking CSS and JS — CSS and JS files stop anything appearing on screen.
- Why you're seeing "no field data" — Google has no real-visitor data for your site yet.
- How to fix oversized and outdated images — Your images weigh far more than they need to.
- How to cut unused JavaScript — You ship JavaScript this page never runs.
- How to fix your cache headers — Returning visitors re-download files they already have.
- Why your score is different on every run — The score is different every time you test.
- Fast on desktop, slow on mobile — Desktop looks fine; the phone test says otherwise.
- Why Search Console still shows the old numbers — You fixed it weeks ago and Search Console hasn't noticed.
- Core Web Vitals assessment: failed — Search Console says failed, PageSpeed says 95 — and both are right.
- Which AI crawlers to allow in robots.txt — You block training bots and accidentally block the ones that cite you.
- Your firewall is blocking AI crawlers — robots.txt allows everyone, yet AI crawlers get a 403 before they read a byte.
- Your content only exists after JavaScript runs — The server sends an empty shell and a script fills it in — AI crawlers see nothing.
- Structured data that AI crawlers actually use — The page is readable but nothing tells a machine what it is.
- llms.txt — what it is, what it isn't, and a template — A cheap bet, not a fix — here's the honest evidence and a template.