=== WP Avoid Slow === Contributors: deshabhishek007, fitehal Tags: performance, speed, optimize, bloat, core-web-vitals Requires at least: 5.0 Tested up to: 6.9.1 Requires PHP: 7.4 Stable tag: 1.2.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html WordPress ships features most sites never use. Here's the off switch. == Description == 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. **WP Avoid Slow gives you the off switch for each one.** = The Off Switches = * **Emoji script** — ~15 KB + 1 HTTP request. Browsers handle emoji natively. * **Embed script** — ~4 KB + oEmbed discovery links in `
`. * **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 the `` that search engines ignore. * **Query strings on assets** — Strips `?ver=` from scripts, styles, and WP 6.5+ Script Modules so CDNs and proxies cache correctly. * **XML-RPC endpoint** — Closes a common brute-force attack vector. * **Heartbeat API** — Reduces admin polling from every 15 s to every 60 s. * **Dashicons on the frontend** — ~35 KB (CSS + font) saved for every logged-out visitor. * **REST API Discovery Link** — Removes `` from ``. Exposes your REST endpoint URL in the page source; safe to remove on standard sites. * **RSS Feed Links** — Removes feed autodiscovery `` tags from ``. Modern browsers no longer act on them. Leave enabled if you publish an RSS feed. * **Speculation Rules (WP 6.8+)** — Disables the Speculation Rules API that prefetches links before users click them. Can inflate analytics, increase bandwidth, and trigger GDPR consent flows without explicit user intent. = 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"` and `type="text/css"` are redundant in HTML5. * **Defer non-critical JavaScript** — Adds `defer` so scripts don't block HTML parsing. jQuery is never deferred. * **Move scripts to footer** — Relocates enqueued scripts from `` to just before ``. jQuery is never moved. = WordPress Behaviour Tweaks = * **Self-pingbacks** — WordPress sends a pingback to your own posts when you link between them. An outbound HTTP request that creates an unwanted comment on the target post. Turned off. * **Capital P filter** — WordPress auto-corrects "Wordpress" to "WordPress" in every title, post, and comment. The filter runs on every string rendered. Remove it if you don't need the autocorrect. * **Limit post revisions** — WordPress stores unlimited revisions. On active editorial sites the database grows silently. This caps revisions at 3 per post. * **Attachment pages** — WordPress creates a full template page for every uploaded image or file. These pages waste crawl budget and have no SEO value on most sites. Sends a 301 redirect to the parent post instead. = Image Performance = * **Google Fonts display:swap** — Without `font-display:swap`, the browser hides text while your Google Font downloads (FOIT). This adds `display=swap` to every Google Fonts URL so visitors see text immediately. * **Add missing image dimensions** — Images without `width` and `height` attributes cause layout shifts (CLS). This 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. Adds `fetchpriority="low"` and `decoding="async"` to all other images. * **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 and adds significant upload processing time. = A nod to YSlow = In 2007 Yahoo! released YSlow — a browser tool that graded pages against a checklist of performance rules. Make fewer HTTP requests. Remove what you don't need. Minimise round trips. Ship 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 fastest request is still the one that never happens. WP Avoid Slow is, in spirit, a YSlow checklist applied to what WordPress ships by default. Most of the toggles here map directly to rules YSlow was preaching almost twenty years ago — they just never had an off switch built into the CMS itself. = 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. == Installation == 1. Upload `wp-avoid-slow` to `/wp-content/plugins/` 2. Activate through the Plugins menu 3. Go to **Settings → Avoid Slow** 4. Turn off what you don't need == Frequently Asked Questions == = Will this break my site? = Each toggle is independent. Safe defaults are on. Risky ones (jQuery Migrate, defer JS, scripts to footer) are off by default. If something breaks — turn that toggle off. Nothing is written to disk. = Does it work on managed hosting (WP Engine, Kinsta, Pressable)? = Yes. Pure PHP hooks, no .htaccess required. = Should I disable XML-RPC? = Only if you don't use Jetpack, the WordPress mobile app, or any XML-RPC client. When in doubt, leave it off. = Should I enable "Defer non-critical JavaScript" or "Move scripts to footer"? = Test on staging first. These two are the most likely to cause issues on complex sites — some themes and plugins rely on scripts being available synchronously in ``. = Does it cache pages? = No. This plugin removes unused WordPress features. For page caching, use a dedicated plugin. = Does it work on WordPress Multisite? = Not currently. WP Avoid Slow is designed and tested for single-site WordPress installs. Multisite introduces complexities the plugin does not yet handle: the activation hook does not fire per sub-site on network activation, there is no network admin settings page, and per-sub-site URL handling has edge cases in subdirectory setups. Activating it on a multisite network may work in basic cases, but it is untested and unsupported. Multisite support is planned for a future release. = How is this different from other performance plugins? = Most performance plugins add things — caching layers, CDN routing, minification pipelines. This one removes things. It's a different job. == Changelog == = 1.2.0 = * New: REST API Discovery Link toggle — removes `` from `` (default ON) * New: RSS Feed Links toggle — removes RSS autodiscovery `` tags from `` (default OFF) * New: Speculation Rules toggle — disables WP 6.8+ prefetch/prerender JSON output (default OFF) * Improvement: Asset Query Strings now also covers WP 6.5+ Script Modules (`script_module_loader_src` filter) — no new toggle needed * Fix: `customize-support` script handle added to protected list — was incorrectly deferred or moved to footer when Defer JS or Move Scripts to Footer were enabled * Reviewed against WordPress 6.9.1 source — all new default frontend outputs assessed; no other unaddressed bloat found * Total: 33 independent toggles across 5 modules = 1.1.1 = * Fix: new toggles introduced in 1.1.0 were showing as off after upgrading from an older version instead of their correct defaults * Fix: activation hook now merges new option keys into existing settings on upgrade — existing user choices are never overwritten * Fix: settings page now merges with defaults before rendering so new toggles always display their intended state even if the stored option row is from an older version * Fix: active switch counter in the page header now counts correctly after an upgrade = 1.1.0 = * New module: WordPress Behaviour Tweaks — disable self-pingbacks, remove Capital P filter, limit post revisions to 3, redirect attachment pages to parent post * New module: Image Performance — Google Fonts display:swap, auto-add missing image dimensions (fixes CLS), LCP fetchpriority, lazy load images, disable PDF thumbnail generation * readme: added multisite FAQ (not yet supported) * readme: added tribute to YSlow philosophy * Tested up to WordPress 6.9.1 * Total: 26 independent toggles across 4 modules = 1.0.0 = * Complete rewrite — no longer depends on .htaccess * 17 independent toggles across two modules, pure PHP hooks * Module 1: The Off Switches — emoji, embeds, RSD, WLW manifest, version tag, shortlink, query strings, XML-RPC, Heartbeat, Dashicons * Module 2: Script & Style Control — jQuery Migrate, Block Library CSS, Global Styles, SVG Duotone, type attributes, defer JS, move scripts to footer * Admin UI: CSS toggle switches replacing checkboxes * Works on any host including managed hosting * Ships with safe defaults — risky toggles are off until you opt in * Settings → Avoid Slow admin page = 0.4 = * Minor fixes = 0.3 = * Minor fixes = 0.2 = * Expire cache fix = 0.1 = * Initial release — .htaccess Expires headers + ETags