A performance plugin for WordPress sites built with Elementor.
Feather reads your saved Elementor data to learn which widgets and assets each page actually uses, then removes the rest. Around that scan, it also turns off WordPress features most sites never use, throttles the parts that run on every admin tick, and cleans rows out of the database that accumulate over time.
Everything Feather does is reversible from the dashboard. Nothing runs against your site from outside it.
Project website: featherplugin.com.
- Disable the WP emoji loader (
wp-emoji-release.min.jsand the inline detection script) - Disable oEmbed discovery and the embed JS bundle
- Disable
jquery-migrateon the frontend - Remove
<meta name="generator">(WordPress version disclosure) - Remove RSD link, Windows Live Writer manifest, shortlink, REST link, and wlwmanifest from
<head> - Disable XML-RPC pingback advertising
- Strip cache-busting query strings (
?ver=…) from static asset URLs - Turn off automatic feed links Elementor sites rarely use
- Slow the admin heartbeat from 15s to 60s (configurable)
- Disable heartbeat entirely on the dashboard and on post-edit screens when you don't need autosave broadcasts
- Limit post revisions (configurable cap; default 5)
- Increase autosave interval
These activate only after a site scan confirms zero usages site-wide for each asset:
- Dequeue Elementor's frontend bundle on pages that aren't built with Elementor
- Dequeue the Font Awesome 4 shim when no widget references it
- Dequeue eicons when no widget references it
- Dequeue Google Fonts loaded by Elementor when no widget uses a Google font
- Remove Elementor's DOM-cruft (empty wrapper divs, redundant inline styles)
- Defer non-critical JavaScript
- Add
loading="lazy"to iframes that don't already have it - Auto-fix
<img>tags missingwidth/heightattributes (prevents layout shift) - Apply
content-visibility: autoto off-screen sections so the browser can skip their work
One-click actions from the Database tab:
- Delete expired transients (rows where
option_name LIKE '_transient_timeout_%'and the value is in the past) - Prune orphaned Elementor revisions beyond a configurable keep count
- Flush oEmbed cache rows (
_oembed_*post meta) - Audit autoloaded options — flag any single option with autoload=
yesover a configurable size threshold
- Take a page-weight snapshot of any URL from your site (bytes transferred, asset count, HTTP request count, response time)
- Compare snapshots over time on the dashboard
- Store the last 90 days of measurements in a custom table; older rows are pruned automatically
- Zero outbound HTTP calls in the default configuration
- No telemetry, no analytics, no remote check-in pings
- The scanner reads
_elementor_datapost meta from your local database only - Page-weight measurements are same-origin loopback
GETrequests to your own URLs viawp_remote_get(), triggered explicitly from the dashboard - No third-party CDNs, no Google Fonts, no remote JS loaded by the admin UI — the React bundle ships pre-built and only depends on WordPress's own bundled scripts
- WordPress 6.0 or newer
- PHP 7.4 or newer
- Elementor (free or Pro) installed for the asset-aware features
- In your WordPress admin: Plugins → Add New.
- Search for Feather Performance.
- Click Install Now, then Activate.
- Open Feather in the admin sidebar, run the welcome scan, and apply a recommended preset.
- Download
feather-performance.zipfrom the Releases page. - In WordPress admin: Plugins → Add New → Upload Plugin.
- Choose the zip, click Install Now, then Activate.
git clone https://github.com/featherr/feather-performance.git
cd feather-performance/ui
npm install
npm run buildThen symlink or copy the repo root into wp-content/plugins/feather-performance/.
Feather detects these on activation and refuses to enable any optimization they already handle:
- WP Rocket
- LiteSpeed Cache
- SiteGround Optimizer
- W3 Total Cache
- Imagify
- Smush
So you can leave your existing caching plugin in place. Feather only fills the gaps it leaves.
Multisite is supported per-site. Network-level controls are planned.
- All admin pages and REST endpoints gate on a custom
manage_feathercapability, mapped tomanage_optionsvia theuser_has_capfilter - Every REST endpoint implements
permission_callback - Input is sanitized (
sanitize_text_field,absint, enum allow-lists); output is escaped (esc_html__,esc_url,esc_attr) - Every
$wpdbquery with user-supplied values usesprepare() - Direct database operations (table truncate, OPTIMIZE TABLE, DELETE for cleanup) are scoped to plugin-owned tables and known WordPress core tables
wp_feather_scan— one row per Elementor-built post, holding widget types, asset handles, and settings flagswp_feather_metrics— page-weight measurement history; auto-pruned to 90 days
Both tables are dropped by uninstall.php when you delete the plugin from WP admin.
.
├── feather-performance.php # Plugin bootstrap
├── uninstall.php # Drops custom tables on plugin deletion
├── src/ # PHP source, PSR-4 autoloaded under Feather\
│ ├── Optimizers/ # Each optimization above lives here
│ ├── Scanner/ # Per-page Elementor data scanner
│ ├── Metrics/ # Page-weight measurement
│ ├── Db/ # Database hygiene tools
│ ├── Rest/ # REST endpoints
│ ├── Admin/ # Admin pages and asset registration
│ └── …
├── ui/ # React admin app (TypeScript)
│ ├── src/
│ └── package.json
├── assets/admin/ # Compiled React bundle (committed)
├── assets/icons/ # Plugin icons
├── assets/img/ # Brand marks
└── languages/ # Translation files
cd ui
npm install
npm run build # production build → ../assets/admin/
npm run start # watch mode for development
npm run lint:js # ESLint via @wordpress/scripts
npm run lint:css # Stylelint via @wordpress/scripts
npm test # Jest unit tests via @wordpress/scriptsdeclare( strict_types=1 );in every file- PSR-4 autoloading under the
Feather\namespace viasrc/Autoloader.php - No Composer runtime dependencies — no
vendor/directory ships
Issues and pull requests are welcome.
- Fork the repository and branch from
main. - Match the surrounding code style.
- Run the linters:
cd ui && npm run lint:js && npm run lint:css. - Open a pull request describing the change.
For larger changes, please open an issue first.
See readme.txt for the WordPress.org changelog, or the Releases page for tagged builds.
- Elementor 4.0.x atomic widget support. Scanner detects atomic widgets (
e-heading,e-button,e-image,e-paragraph,e-divider,e-svg,e-self-hosted-video,e-youtube,e-component) and atomic element types (e-flexbox,e-div-block,e-tabs,e-tabs-menu,e-tab,e-tabs-content-area,e-tab-content) inside_elementor_data. AtomicAssetGateoptimizer (gated). New featuref.elementor.skip_atomic_chain. On Elementor pages that contain only legacy widgets, dequeues the v4 atomic widget handler bundle —elementor-v2-widgets-frontend,elementor-v2-frontend-handlers,elementor-v2-alpinejs,elementor-tabs-handler,elementor-youtube-handler. Auto-bails on Elementor Pro to protect theme-builder injected atomic widgets.ElementorHostFirewalloptimizer (gated). New featuref.elementor.network_firewall. Hookspre_http_requestat priority 1 and refuses every outbound request whose host matches(^|\.)elementor\.com$, unless the request is user-initiated (AJAX non-heartbeat, REST, editor page load). Catches every background telemetry / marketing / discovery vector at the network layer — including future ones Elementor may add. Coexists withApiFetcherDisabler.- Master "Pause all optimizations" toggle. New
optimizers_pausedtop-level setting onSettingsRepository. When true,Plugin::apply_optimizers()returns before registering any optimizer hooks. Exposed via a<PauseAllCard />component at the top of the React Dashboard, with optimistic-update + rollback behavior. PerPageAssetTrimmernow dropselementor-tabs-handlerandelementor-youtube-handlerper-page when the page's scan row doesn't list the corresponding atomic element.UnusedWidgetBundleStrippernew branch deregisters the entire v4 chain atwp_default_scriptswhenScanRepository::has_any_atomic_widgets_site_wide()returns false and Elementor Pro is not active.WidgetAssetMap::introspection_failures()/reset_introspection_failures()static accessors — count and reset rejected handle entries per request.ScanRepository::flags_for_post()— symmetric tohandles_for_post(), returns decodedsettings_flagsmap for a single post.ScanRepository::has_any_atomic_widgets_site_wide()— site-wide accessor backed by the existing aggregate cache.
- Default theme switched from
systemtolighton fresh installs. Existing users keep their stored preference; thesystemoption remains selectable. feather_aggregated_scan_verdictsaggregate now carrieshas_atomic_widgets_anywhere: boolfield.- Scan rows'
settings_flagsJSON now carrieshas_atomic_widgets: bool. WidgetAssetMap::introspect()now validates each declared handle against/^[a-z0-9_-]+$/. Garbage entries (e.g., the class-FQN-as-error strings some third-party widgets leak from brokenget_*_depends()methods) are filtered out and the rejection counter is incremented.WidgetAssetMapnow stripsswiperande-swiperfrom anywp-widget-*introspection result — works around an upstream bug in Elementor'sWidget_WordPressclass that incorrectly declares those deps for every WordPress sidebar widget.WidgetAssetMap::defaults()overlay addse-tabs => ['elementor-tabs-handler'].
MetricsEndpoint::capture()now re-reads viaMetricsRepository::latest()after save, so the response carriesrecorded_at. Fixes the Dashboard "Last measured" tile showing "Never" immediately after running a measurement.- Dashboard "Pause all optimizations" card now renders with proper spacing — label and description stack on separate lines, toggle sits on the right with a flex layout, mobile breakpoint at 600px drops the toggle below the text. Warning gradient applied when paused (light + dark mode variants).
- New file:
src/Optimizers/Elementor/AtomicAssetGate.php - New file:
src/Optimizers/Elementor/ElementorHostFirewall.php - New file:
ui/src/components/PauseAllCard.tsx - Plugin orchestrator (
Plugin::apply_optimizers) now resolvesSettingsRepositoryonce at the top and consults it for the pause flag before any feature iteration.
Initial release.
Feather Performance is released under the GNU General Public License v2.0 or later.
Copyright (C) 2026 Feather
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
Built by Feather — featherplugin.com