Skip to content

fix(optimize): replace load event listeners in JS Delay mode - #1031

Open
faisalahammad wants to merge 3 commits into
litespeedtech:devfrom
faisalahammad:fix/629-js-delay-load-event
Open

fix(optimize): replace load event listeners in JS Delay mode#1031
faisalahammad wants to merge 3 commits into
litespeedtech:devfrom
faisalahammad:fix/629-js-delay-load-event

Conversation

@faisalahammad

Copy link
Copy Markdown
Contributor

Summary

Fixes issue where scripts delayed by LiteSpeed Cache (optm-js_defer = 2 / JS Delay mode) attaching event listeners to load event fail to execute because the native browser load event fires before delayed scripts run.

Fixes #629

Changes

src/optimize.cls.php

Before:

if ($file_type == 'js') {
    $con = str_replace('DOMContentLoaded', 'DOMContentLiteSpeedLoaded', $con);
    // $con = str_replace( 'addEventListener("load"', 'addEventListener("litespeedLoad"', $con );
}

After:

if ($file_type == 'js') {
    $con = $this->_replace_js_events( $con );
}

private function _replace_js_events( $con ) {
    $con = str_replace( 'DOMContentLoaded', 'DOMContentLiteSpeedLoaded', $con );
    $con = preg_replace( '/(?<!\.)\b(window\.|document\.)?addEventListener\(\s*([\'"])load\2/', 'addEventListener($2DOMContentLiteSpeedLoaded$2', $con );
    $con = preg_replace( '/((?:$|jQuery)\(\s*(?:window|document)\s*\)\s*\.on\(\s*)([\'"])load(?:\.[\w-]+)?\2/', '$1$2DOMContentLiteSpeedLoaded$2', $con );
    $con = preg_replace( '/\bwindow\.onload\s*=/', 'window.addEventListener("DOMContentLiteSpeedLoaded",', $con );
    return $con;
}

Why: Replaces DOMContentLoaded and load event listeners on window and document with DOMContentLiteSpeedLoaded in JS Delay mode. Preserves element-level listeners (such as image load or XMLHttpRequest load listeners).

Testing

Test 1: JS Delay Event Listener Replacement

  1. Enable JS Delay (optm-js_defer = 2) in LiteSpeed Cache settings.
  2. Load a page containing delayed scripts with window.addEventListener('load', ...) or $(window).on('load', ...) or window.onload = ....
  3. Interact with the page to trigger JS delay loading.
    Result: load event handlers execute cleanly upon dispatch of DOMContentLiteSpeedLoaded.

Test 2: Element-Level Load Listeners

  1. Inspect image load listeners (img.addEventListener('load', ...)).
    Result: Element-level image and XHR load listeners are preserved untouched and function as expected.

@faisalahammad
faisalahammad changed the base branch from master to dev August 7, 2026 17:53
@timotei-litespeed

Copy link
Copy Markdown
Contributor

@faisalahammad please make sure there is just 1 change per PR. I see multiple changes(different bugs) added.

- 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 litespeedtech#1031
@faisalahammad
faisalahammad force-pushed the fix/629-js-delay-load-event branch from dc223f3 to 996ba50 Compare August 7, 2026 20:26
@faisalahammad

Copy link
Copy Markdown
Contributor Author

Updated PR to contain only 1 change for JS Delay load event listener replacement. Removed all other unrelated commits.

@timotei-litespeed

Copy link
Copy Markdown
Contributor

@faisalahammad I will look over the code on Monday. Thank you

- 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 litespeedtech#1031

Signed-off-by: Faisal Ahammad <faisalahammad24@gmail.com>
@faisalahammad

Copy link
Copy Markdown
Contributor Author

Confirmed. Kept this PR to one change. Also fixed the new method @SInCE to 8.0 and added an 8.0 changelog entry.

@faisalahammad

Copy link
Copy Markdown
Contributor Author

Fixed the JS Delay exclusion regression in b02282e. The litespeed_optm_cssjs callback now accepts the third source argument and skips load-event rewriting when the source matches cfg_js_defer_exc. Non-JS content remains unchanged. Verified with PHP lint, PHPCS, focused exclusion/event rewrite tests, and an independent code review. No changes were made to the separate event-pattern coverage items.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix js delayed bug for load event

2 participants