The Off Switch (formerly WP Avoid Slow)
WordPress prioritises backwards compatibility. That’s a feature. It also means every install ships with things you didn’t ask for.
An emoji CDN script. An oEmbed script. A Windows Live Writer manifest (discontinued 2017). Dashicons loaded for logged-out visitors. Heartbeat polling every 15 seconds. A version tag that tells the world exactly which WordPress you’re running.
None of these are bugs. They’re just not needed on most sites.
The Off Switch lets you disable each one, individually.
The Off Switches
- Emoji script — ~15 KB + 1 HTTP request. Browsers handle emoji natively.
- Embed script — ~4 KB + oEmbed discovery links in
<head>. - RSD link — Really Simple Discovery. Only needed for legacy XML-RPC clients.
- WLW manifest — Windows Live Writer has been discontinued since 2017.
- WP version tag — Stops advertising your WordPress version to the world.
- Shortlink — Removes
<link rel="shortlink">from<head>and HTTP headers. Search engines ignore it. - Asset query strings — Strips
?ver=from scripts, styles, and WP 6.5+ Script Modules so CDNs and proxies cache correctly. - XML-RPC — Closes a common brute-force attack vector.
- Heartbeat API — Reduces admin polling from every 15 s to every 60 s.
- Dashicons (frontend) — ~35 KB (CSS + font) saved for every logged-out visitor.
- REST API Discovery Link — Removes
<link rel="https://api.w.org/">from<head>. Safe to remove on standard sites. - RSS Feed Links — Removes feed autodiscovery
<link>tags from<head>. Modern browsers no longer act on them. Leave enabled if you publish an RSS feed. - Speculation Rules (WP 6.8+) — Disables the WP 6.8+ Speculation Rules API that prefetches links before users click. Can inflate analytics, increase server bandwidth, and trigger consent flows on unfetched pages.
- Disable All Feeds — Redirects all RSS and Atom feed URLs to the homepage. For sites with no RSS subscribers.
- Comment Auto-Links — Stops WordPress from converting plain-text URLs in comments into clickable links.
- Editor Autosave — Deregisters the autosave script that POSTs editor content to the server every 60 seconds. For teams that prefer explicit saves.
- DNS Prefetch — Removes all
<link rel="dns-prefetch">hints from<head>. Redundant when Emojis and Embeds are already disabled.
Script & Style Control
- jQuery Migrate — ~30 KB. Modern themes don’t need it.
- Block Library CSS — ~7 KB loaded on every page, even with no Gutenberg blocks.
- Global Styles (theme.json CSS) — 10–50 KB inline CSS from block themes.
- SVG Duotone Filters — Hidden SVG blob injected on every page, even with no duotone images.
- Script/Style type attributes —
type="text/javascript"andtype="text/css"are redundant in HTML5. - Defer non-critical JavaScript — Adds
deferso scripts don’t block HTML parsing. jQuery is never deferred. - Move scripts to footer — Relocates enqueued scripts from
<head>to just before</body>. jQuery is never moved.
WordPress Behaviour Tweaks
- Self-pingbacks — WordPress pings your own posts when you link between them — a wasted HTTP request that creates an unwanted comment on the target post.
- Capital P filter — WordPress corrects «WordPress» to «WordPress» on every rendered string. Remove if you don’t need the autocorrect.
- Limit post revisions — WordPress stores unlimited revisions per post. Caps revisions at 3 to prevent silent database growth on active editorial sites.
- Attachment pages — WordPress creates a full template page for every uploaded file. These waste crawl budget on most sites. Sends a 301 redirect to the parent post instead.
Database & Query
- Expired Transients — Schedules a daily cleanup of expired transient rows in wp_options. Useful on low-traffic sites where WP-Cron can go days without firing.
- Abandoned Auto-Drafts — WordPress creates an auto-draft every time the post editor opens. Abandoned sessions leave these rows permanently. Runs a daily sweep to delete auto-drafts older than 30 days.
- Skip Row Count on Singles — On every single post or page, MySQL runs SQL_CALC_FOUND_ROWS to count total matching rows — a full index scan only needed for paginated archives. Removes that sub-query on all singular views.
- Adjacent Post Links — WordPress queries the previous and next post on every single post page to output
<link rel="prev/next">in<head>. Two extra DB queries per page load. Google dropped support for these SEO hints in 2019.
Image Performance
- Google Fonts display:swap — Without
font-display:swap, the browser hides text while your Google Font downloads (FOIT). Addsdisplay=swapto every Google Fonts URL so visitors see text immediately. - Add missing image dimensions — Images without
widthandheightattributes cause layout shifts (CLS). Reads dimensions from attachment metadata and injects them automatically. - LCP image priority — Adds
fetchpriority="high"to the first content image so the browser loads it before lower-priority resources. Addsfetchpriority="low"anddecoding="async"to all others. - Lazy load images — Adds
loading="lazy"to images below the fold. The first image is never lazy-loaded — it is the LCP candidate and must load immediately. - Disable PDF thumbnails — WordPress generates thumbnail previews for every uploaded PDF when ImageMagick is available. Rarely used on the frontend; adds significant upload processing time.
Admin Hardening
- Block User Enumeration — WordPress redirects
?author=1to/author/username/, exposing registered usernames. Intercepts those requests and redirects to the homepage before the username is revealed. - Disable Author Archives — Redirects all
/author/username/pages to the homepage. For sites with no author profile pages. - Disable File Editor — Defines
DISALLOW_FILE_EDITto remove the plugin and theme code editor from wp-admin. Eliminates a code-injection surface a compromised admin account could exploit. - Disable Application Passwords — Removes the Application Passwords UI and stops all tokens from being accepted. For sites that don’t use REST API or XML-RPC integrations.
- Suppress Admin Email Check — Disables the periodic full-screen prompt asking admins to confirm their email address. One less interruption, no functional change.
- Remove X-Pingback Header — Strips
X-Pingback:from every HTTP response, stopping the site from advertising its XML-RPC endpoint URL to scanners. - Clean Admin Bar — Removes the WordPress logo dropdown, the duplicate «Visit Site» link, and the admin bar search for a less cluttered editing environment.
- Hide Update Nag for Non-Admins — Hides the core update notice from editors and contributors who cannot action it. Administrators still see it normally.
Block Editor
- Remote Block Patterns — WordPress fetches patterns from api.wordpress.org on every editor load. An outbound HTTP request that adds latency even if editors never use the Pattern inserter. Local patterns from themes and plugins are unaffected.
- Core Block Patterns — Removes WordPress’s built-in block patterns (headers, galleries, CTAs) from the Pattern inserter. For sites using custom patterns or none at all.
- Block Directory — The editor includes a live search of wordpress.org that lets users install new blocks without leaving the editor. Remove it to keep block installation under your control.
- Font Library (WP 6.5+) — WordPress 6.5 added a Font Library panel for uploading custom fonts and browsing Google Fonts in the Site Editor. Remove it if fonts are managed through your theme or code.
- Widget Block Editor (WP 5.8+) — WordPress 5.8 replaced the classic Widgets screen with a block-based editor. Restores the classic screen for classic themes, sidebar widgets, and page builders.
WooCommerce
These toggles are only shown when WooCommerce is active.
- Cart Fragments — wc-cart-fragments.js fires an AJAX request to keep mini-cart counts accurate when the Cart Widget is rendered (~3 KB + 1 request). Disable on stores where the Cart Widget is not used, or where real-time cart accuracy across tabs is not needed.
- WooCommerce Generator Tag — Removes
<meta name="generator" content="WooCommerce x.x.x">from<head>. Same reason as the WordPress version tag: stops advertising which version of WooCommerce you’re running. - WC Scripts on Non-WC Pages — WooCommerce loads ~114 KB of CSS and JS on every page (woocommerce-general, woocommerce-layout, woocommerce-smallscreen, woocommerce.js, wc-add-to-cart.js, and woocommerce-blocktheme on block themes). Dequeues them all on non-shop, non-cart, non-checkout, and non-account pages. Up to ~30 KB gzipped saved per non-WooCommerce page.
- Password Strength Meter — WooCommerce already restricts wc-password-strength-meter to checkout and My Account pages where a password is required. This toggle is a secondary safety net for themes or plugins that enqueue the script more broadly, removing zxcvbn (~80 KB gzipped) wherever it loads unnecessarily.
- Status Dashboard Widget — Removes the WooCommerce Status meta box from the WordPress admin dashboard. For stores managed from the WooCommerce screens directly.
- WC Block Patterns — WooCommerce registers its own block patterns in the editor inserter. Remove them if your store does not use WooCommerce-provided patterns for page design — declutters the inserter and removes a small init overhead.
- WC Legacy Widgets — WooCommerce registers 12 legacy widgets on every page load even on block-based themes. Unregistering them removes the initialisation overhead and hides them from Appearance → Widgets.
- WC Version Header — Removes the X-WooCommerce-Version HTTP response header that some WooCommerce extensions inject, closing the same version-leakage vector as the generator tag toggle.
- Stripe Gateway Scripts — Prevents the WooCommerce Stripe Gateway from loading Stripe.js on product and cart pages when the Payment Request Button (Apple Pay / Google Pay) is disabled in the Stripe settings.
A nod to YSlow
In 2007 Yahoo! released YSlow — a browser tool that graded pages against a checklist of performance rules: fewer HTTP requests, smaller payloads, nothing the browser didn’t ask for. Steve Souders and the Yahoo! Exceptional Performance team gave the whole industry a shared vocabulary for why pages were slow, and a practical list of things to fix.
Browsers got faster. Servers got faster. Bandwidth got cheaper. The fundamentals didn’t change.
The Off Switch is, in spirit, a YSlow checklist applied to what WordPress ships by default. The fastest request is still the one that never happens.
What it doesn’t do
- No caching — use a dedicated caching plugin for that.
- No CDN — use Cloudflare, BunnyCDN, or your host’s CDN.
- No .htaccess writes — pure PHP hooks, works on any host including managed hosting.
- No upsell. No Pro version. No phone-home.
How it works
Every toggle is a named WordPress hook removal or filter. You can read the entire logic in one file per module. No compiled assets. No build step. No obfuscation.
Who it’s for
Developers and agencies who know what these features do — and know their site doesn’t need them.
Not sure what a toggle does? Leave it off. Each one is independent.
