Added — Sitemap-based cache preloading
The preloader now builds its warmup queue from XML sitemaps — Yoast SEO, Rank Math, WordPress core sitemaps, a custom sitemap URL, or any sitemap declared in robots.txt — instead of only scanning the posts tables, so taxonomy, author, and date archives get warmed too. Sitemap fetches are XXE-safe, capped (depth 2, 200 files, 10,000 URLs), transient-cached for an hour, and restricted to the site's own host; URLs that the cache exclusion rules would never store are filtered out before queueing. When no sitemap is reachable the preloader silently falls back to the previous content scan, and the WP-CLI wp sol preload output now reports which URL source was used.
Added — Per-path cache TTL rules
A new cache_ttl_rules setting (up to 20 rules of pattern + ttl_hours, wildcard * supported, most-specific/longest match wins) gives individual URL paths their own cache lifespan — e.g. /blog/* at 1 hour, /docs/* at 1 month — while unmatched URLs keep the global TTL. Rules are baked into the early-boot settings file, so both pre-boot delivery and the cron garbage collector honor them.
Added — Logged-in user cache
A new user_cache setting (off by default) serves and writes per-user cached pages for logged-in visitors, keyed by the username from the auth cookie so two users never share a file. Session-sensitive cookies (WooCommerce, EDD, comment/password cookies, and any user-configured exclusions) still hard-bypass the cache. Per-user files are purged on profile update, password reset, and account deletion without touching other users, and Vary: Cookie is emitted while the feature is enabled. Filterable via sol_user_cache_enabled.
Added — CDN URL rewriting
New SOL_CDN module: point a CDN hostname (BunnyCDN, CloudFront, KeyCDN, …) at the origin and asset URLs in the final HTML — uploads, theme/plugin assets, wp-includes, and/or CSS/JS files, each toggleable — are rewritten to the CDN, with per-line exclusion patterns. Rewriting runs on the engine's sol_page_contents_before_output filter after all other optimizers and before the cache write, so cached pages contain CDN URLs and cache hits are never double-processed.
Added — Kill Bloat toggles
Three new switches (all off by default): disable XML-RPC (xmlrpc_enabled filter plus X-Pingback header removal), disable RSS/Atom feeds (head links removed, feed requests get a 403 with a filterable message), and remove jQuery Migrate on the front end (dependency stripped rather than deregistered, so scripts declaring it can't fatal).
Changed — WooCommerce orders purge only what they affect
woocommerce_new_order / woocommerce_checkout_order_processed no longer clear the entire site cache (and Cloudflare edge) on every sale. The new targeted purge walks each order's products through the existing per-post invalidation map — product page, shop page, product category/tag archives — and purges only those URLs, locally and at the edge. sol_woo_purge_urls filter for extensions; sol_woo_order_full_cache_purge restores the old behavior.
Changed — FOUC hardening for Critical CSS
Critical CSS is now placed as early as legally possible in <head> (before every external stylesheet), a static no-hide failsafe flips any deferred sheet still stuck at media="print" to media="all" shortly after window-load (also shipped on RUCSS pages for their deferred fallback sheets), critical cache files carry a stylesheet fingerprint sidecar so a page never pairs with a previous design's critical block, and font-display: swap injection moved to the inject choke point so legacy and cloud-rewarmed files are covered too. Pages without critical CSS remain fully render-blocking — no blank-page gates anywhere.
Changed — Page-cache drop-in self-heal is now visible
When requirements_check() rebuilds a missing advanced-cache.php (e.g. after a server or path migration), a dismissible admin notice reports that caching was briefly inactive and is running again, instead of the drop-in silently vanishing.
Security
- The temporary wp-config backup written while toggling the
WP_CACHE constant now lives
in the system temp directory (with a guarded fallback) instead of the web root, closing a brief window where database credentials could be served as plain text.
- Cloud render service (api.speedoflight.pro): closed a WebRTC/UDP bypass around the
SSRF guard, hardened client-IP handling for the token rate limiter, added URL-length and stylesheet-input caps, fixed a failed-navigation case that could return an "empty but successful" render plan, rotated the shared secret, and expanded the test suite (111 tests green).
Added — Non-destructive image optimization with restore
Image conversion no longer deletes the original file: JPEG/PNG sources stay in the uploads directory by default, and every conversion writes a _sol_converted record (original path, URL, metadata snapshot, generated files, content URL rewrites, byte counts) so the plugin knows exactly what it changed. Converted images can be reverted — per attachment via a new "Restore original" row action in the Media Library, or in bulk via "Restore all originals" on the Bulk Compression screen — which re-points the attachment and content URLs at the original file and deletes the generated WebP/AVIF versions. A new "Delete originals after conversion" setting (off by default) restores the old space-saving behavior at the cost of revertibility. Conversion output is validated with getimagesize() and the reported format now reflects what the encoder actually produced rather than the requested format; content URLs are only rewritten when the target file provably exists, and all file deletes are realpath-confined to the uploads directory.