Performance Optimisation is built the way a performance tool should be: engineering-first, not settings-first. Plenty of plugins hand you a wall of checkboxes and hope you find the right combination; this one starts from how a WordPress request actually executes — which bytes get minified, when queries hit the database, and what runs before your theme loads. Version 1.9.0 packages that approach into a single plugin covering page and object caching, asset control, media conversion, database hygiene, and field monitoring.
Module map
- Page cache —
advanced-cache.phpdrop-in with preload and targeted purge - Object cache —
object-cache.phpdrop-in plus a Redis connect helper - Minification — stream-read engines for CSS, JS, and HTML in
includes/minify/* - Used CSS — generated per page so above-the-fold rendering waits on less
- Script defer and delay — exclusion lists for anything that must not wait
- Lazy loading — images and embeds loaded as they enter the viewport
- Image conversion — WebP/AVIF output served where supported
- Database cleanup — revisions, auto-drafts, drafts, trash/spam, expired transients, orphan post-meta; on demand or scheduled
- Google Fonts — hosted locally instead of third-party requests
- Server rules — .htaccess/nginx rule generation
- Purge integration — CDN purger plus Varnish purge
- Monitoring — RUM beacon, Server-Timing headers, PageSpeed Insights integration
- Suggestion engine — points at what to enable next
- Granular exclusions — per-post metabox wired into the pipeline
- Automation surface — REST endpoints, system info, logs
Engineering decisions
Minifiers stream instead of string-replacing
The CSS, JS, and HTML minifiers read input through streams rather than loading whole files into memory and running regex passes over strings. Memory use stays flat no matter how large the stylesheet is — there is no fully loaded duplicate of the file sitting in RAM while it gets rewritten.
Caching hooks in early through drop-ins
Page caching lives in an advanced-cache.php drop-in that WordPress loads before plugins and themes execute. A cache hit serves static HTML without bootstrapping the rest of the stack, which is where the TTFB reduction comes from. Object caching uses the matching object-cache.php drop-in, so repeated database queries collapse into reads from Redis.
Per-page control sits inside the enqueue pipeline
A metabox on each post excludes specific scripts and styles from optimization on that URL. It hooks into the same enqueue pipeline the defer and delay modules read, so a global exclusion list and a per-page exclusion behave identically — one mechanism, two scopes.
Developer surface
Every stage is filterable. Exclusion lists are arrays you extend from your own code, purge cycles can be wrapped, and nginx rules, Varnish limits, Server-Timing output, and debug logging all have dedicated filters. On the command line, wp wppo cache status, wp wppo object_cache ping, and wp wppo database revisions cover routine operations.
- Cache lifecycle:
wppo_before_cache_clear,wppo_after_cache_clear,wppo_cache_page_html - Asset exclusions:
wppo_exclude_minification,wppo_exclude_defer_js,wppo_exclude_delay_js - Infrastructure:
wppo_object_cache_dropin_path,wppo_nginx_rules,wppo_varnish_purge_max_urls - Measurement:
wppo_server_timing_enabled,wppo_lazyload_iframe_allowed,wppo_video_placeholder_html,wppo_video_play_button_html - Limits and output:
wppo_filesize_limit_bytes,wppo_inline_combined_css,wppo_debug_log - Cleanup:
wppo_database_cleanup_completed
A real-world filter: keep one fragile script out of minification without turning the module off.
add_filter( 'wppo_exclude_minification', function ( $handles ) {
$handles[] = 'third-party-carousel';
return $handles;
} );Requirements
| Requirement | Value |
|---|---|
| Version | 1.9.0 |
| WordPress | 6.2+, tested up to WP 7.1 |
| PHP | 8.2+ |
| Author | Nilesh Kanzariya |
| License | GPL-2.0-or-later |
Where to get it
Source code, releases, and issue tracking live on GitHub. Configuration guides for every module start at the documentation hub.
Enable progressively
Turn modules on in stages: page cache first, then object cache, then assets. Measure after each step so you know exactly which change moved the number.