keeps every * attribute — defer, async, type, id — with only its src swapped. They * are never inlined: inline scripts ignore defer/async, so inlining made * deferred scripts run immediately and out of order and destroyed * browser caching. * * 0.1.17 (BUG-018): sources that are ALREADY minified are left alone. * Re-minifying a build-tool bundle gains 0-2% and the regex-based * library mis-tokenises some large webpack bundles (Site Kit: a * `"https://..."` string was eaten as a line comment -> SyntaxError). * See looks_minified(). * * @package CachingOut */ if ( ! defined( 'ABSPATH' ) ) { exit; } use MatthiasMullie\Minify\JS; /** * JavaScript minifier. * * Uses MatthiasMullie\Minify\JS for safe, parser-based minification * instead of regex-based whitespace and comment stripping. * * @since 0.1.0 */ class CachingOut_Minify_JS { /** * Average line length (bytes) above which a script is treated as * already minified. Hand-written sources average 30-130; every * build-tool bundle measured (WP core, Complianz, 60 Site Kit * chunks) averages 300+ and most are a single multi-KB line. * * @since 0.1.17 * @var int */ const MINIFIED_LINE_LENGTH = 250; /** * Plugin settings instance. * * @since 0.1.0 * @var CachingOut_Settings */ private $settings; /** * Shared exclusions registry. * * @since 0.1.0 * @var CachingOut_Optimization_Exclusions */ private $exclusions; /** * Minified-file store. * * @since 0.1.16 * @var CachingOut_Minified_Files */ private $files; /** * Constructor. * * @since 0.1.0 * * @param CachingOut_Settings $settings Settings instance. * @param CachingOut_Optimization_Exclusions $exclusions Shared exclusions. * @param CachingOut_Minified_Files|null $files Optional store (tests). */ public function __construct( CachingOut_Settings $settings, CachingOut_Optimization_Exclusions $exclusions, CachingOut_Minified_Files $files = null ) { $this->settings = $settings; $this->exclusions = $exclusions; $this->files = $files ? $files : new CachingOut_Minified_Files(); } /** * Output buffer callback — applies JS minification to the full HTML. * * @since 0.1.0 * * @param string $html Full page HTML. * @return string Transformed HTML. */ public function filter( $html ) { if ( '' === $html ) { return $html; } // BUG-013: pipeline always invokes filter(); must re-check the toggle. if ( ! $this->settings->get( 'file_optimization', 'minify_js', false ) ) { return $html; } // Minify inline ' ); if ( false !== $pos_end_open && false !== $pos_begin_end ) { $tag_head = substr( $full_tag, 0, $pos_end_open + 1 ); $tag_tail = substr( $full_tag, $pos_begin_end ); return $tag_head . $minified . $tag_tail; } return $full_tag; } /** * Callback for