From 996ba5007660498bdd250c310aa568bf529cc305 Mon Sep 17 00:00:00 2001 From: Faisal Ahammad Date: Sat, 8 Aug 2026 02:26:17 +0600 Subject: [PATCH 1/3] fix(optimize): replace load event listeners in JS Delay mode - Replace DOMContentLoaded and load event listeners with DOMContentLiteSpeedLoaded for delayed scripts - Scope load event replacements to window/document to avoid affecting element-level image/XHR listeners - Preserves window/document prefixes and enforces string subject guard Addresses PR feedback. Refs #1031 --- src/optimize.cls.php | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/optimize.cls.php b/src/optimize.cls.php index 8b50f0d63..541146417 100644 --- a/src/optimize.cls.php +++ b/src/optimize.cls.php @@ -90,8 +90,7 @@ public function init() { 'litespeed_optm_cssjs', function ( $con, $file_type ) { if ($file_type == 'js') { - $con = str_replace('DOMContentLoaded', 'DOMContentLiteSpeedLoaded', $con); - // $con = str_replace( 'addEventListener("load"', 'addEventListener("litespeedLoad"', $con ); + $con = $this->_replace_js_events( $con ); } return $con; }, @@ -1005,8 +1004,8 @@ private function _js_inline_defer( $con, $attrs = false, $minified = false ) { if ($this->cfg_js_defer === 2) { // Drop type attribute from $attrs $attrs = Utility::remove_attr( $attrs, 'type' ); - // Replace DOMContentLoaded - $con = str_replace('DOMContentLoaded', 'DOMContentLiteSpeedLoaded', $con); + // Replace DOMContentLoaded and load event listeners + $con = $this->_replace_js_events( $con ); return '' . $con . ''; // return ''; // return '' . $con . ''; @@ -1015,6 +1014,22 @@ private function _js_inline_defer( $con, $attrs = false, $minified = false ) { return ''; } + /** + * Replace JS DOMContentLoaded and load event listeners for JS Delay mode + * + * @since 7.0 + */ + private function _replace_js_events( $con ) { + if ( empty( $con ) || ! is_string( $con ) ) { + return $con; + } + + $con = str_replace( 'DOMContentLoaded', 'DOMContentLiteSpeedLoaded', $con ); + $con = preg_replace( '/(? Date: Tue, 11 Aug 2026 03:21:16 +0600 Subject: [PATCH 2/3] fix(optm): correct @since and add 8.0 changelog for JS Delay load events - Change _replace_js_events @since from 7.0 to 8.0 - Preserve jQuery event namespaces on rewritten load listeners - Add 8.0 changelog entry for JS Delay load event fix Addresses PR feedback. Refs #1031 Signed-off-by: Faisal Ahammad --- readme.txt | 1 + src/optimize.cls.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/readme.txt b/readme.txt index 5d77ddc24..c013aefee 100644 --- a/readme.txt +++ b/readme.txt @@ -259,6 +259,7 @@ You can report security bugs through the Patchstack Vulnerability Disclosure Pro = 8.0 - Coming soon 2026 = * 🌱**OptiMax** OptiMax to maximize the page score. +* **Optimize** Fixed JS Delay mode not executing `load` event listeners. (#629) = 7.9 - Aug 5 2026 = * **Cloud** Changed Health service to run asynchronously, resuming through WP cron when the cloud defers the request. diff --git a/src/optimize.cls.php b/src/optimize.cls.php index 541146417..1c1efd5d5 100644 --- a/src/optimize.cls.php +++ b/src/optimize.cls.php @@ -1017,7 +1017,7 @@ private function _js_inline_defer( $con, $attrs = false, $minified = false ) { /** * Replace JS DOMContentLoaded and load event listeners for JS Delay mode * - * @since 7.0 + * @since 8.0 */ private function _replace_js_events( $con ) { if ( empty( $con ) || ! is_string( $con ) ) { @@ -1026,7 +1026,7 @@ private function _replace_js_events( $con ) { $con = str_replace( 'DOMContentLoaded', 'DOMContentLiteSpeedLoaded', $con ); $con = preg_replace( '/(? Date: Tue, 11 Aug 2026 03:58:13 +0600 Subject: [PATCH 3/3] fix(optm): skip event rewrite for excluded scripts --- src/optimize.cls.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/optimize.cls.php b/src/optimize.cls.php index 1c1efd5d5..ce1557a52 100644 --- a/src/optimize.cls.php +++ b/src/optimize.cls.php @@ -88,14 +88,14 @@ public function init() { if ($this->cfg_js_defer == 2) { add_filter( 'litespeed_optm_cssjs', - function ( $con, $file_type ) { - if ($file_type == 'js') { + function ( $con, $file_type, $src ) { + if ($file_type == 'js' && !Utility::str_hit_array($src, $this->cfg_js_defer_exc)) { $con = $this->_replace_js_events( $con ); } return $con; }, 20, - 2 + 3 ); }