) are rare
* in real post content; we leave those alone with a pre-pass that
* stubs out script / style / pre blocks before rewriting.
*
* @package XSpeed
*/
declare(strict_types=1);
namespace XSpeed;
defined( 'ABSPATH' ) || exit;
final class Lazy_Loader {
/**
* In-process counter for above-the-fold skipping. Reset by
* process_html on every call so a fresh post starts at 0.
*
* @var int
*/
private static $image_counter = 0;
/**
* Eager budget for inline-style backgrounds. Separate from images: a
* hero is either an
or a background, and the passes run one after
* the other, so one shared counter would hand the budget to whichever
* pass runs first rather than to what sits first on the page.
*
* @var int
*/
private static $background_counter = 0;
/**
* Settings cache (one read per request).
*
* @var array|null
*/
private static $opts = null;
/**
* Per-URL dimension cache (md5(src) => [w,h] | 0 for known-failure),
* hydrated from the `xspeed_img_dims` transient once per request.
*
* @var array|null
*/
private static $src_dims_cache = null;
/**
* True while a background pass is resolving dimensions.
*
* Front-end renders read the cache and never fetch; a warm pass is the
* one thing allowed to pay the network cost, because no visitor is
* waiting on it.
*
* @var bool
*/
private static $warming = false;
/**
* Main entry point: take rendered HTML, return rewritten HTML.
* Pure function aside from the static counters.
*/
public static function process_html( string $html ): string {
if ( '' === $html ) {
return $html;
}
$opts = self::opts();
// NOTE: the eager-load budget counter is NOT reset here. process_html
// runs once per filter pass — the_content, post_thumbnail_html, and
// once per get_avatar — so resetting per call let the featured image,
// the first content image, AND every comment avatar each claim an
// "eager" slot, defeating the budget. The counter is reset once per
// page render via reset_state() on template_redirect, so it now
// accumulates across all passes as intended. (FBS-82172 Bug 1)
// Stub out