Skip to content

Core: Refactor loops to avoid going behind array bounds#5839

Open
mgol wants to merge 1 commit into
jquery:mainfrom
mgol:loops-no-outside-bands
Open

Core: Refactor loops to avoid going behind array bounds#5839
mgol wants to merge 1 commit into
jquery:mainfrom
mgol:loops-no-outside-bands

Conversation

@mgol
Copy link
Copy Markdown
Member

@mgol mgol commented May 11, 2026

Summary

Reaching behind array bounds - which is what effectively happens if you check for null/undefined value instead of doing a length check - can trigger deopts in various JS engines. Switch to regular length-based loops.

In the past, this was impractical as IE <9 used to clobber the length property if an element with the name="length" attribute was present, but this is no longer a concern.

Checklist

@mgol mgol self-assigned this May 11, 2026
@mgol
Copy link
Copy Markdown
Member Author

mgol commented May 11, 2026

Current size diffs:

main @35789e7687d31512072098ce0d826079904938d2
   raw     gz     br Filename
  +146    +38    +35 dist/jquery.min.js
  +133    +35    +47 dist/jquery.slim.min.js
  +146    +41    +54 dist-module/jquery.module.min.js
  +133    +33    +27 dist-module/jquery.slim.module.min.js

// results (starting at index 1 because index 0 is always kept), then
// splice away the tail of duplicates.
for ( ; i < results.length; i++ ) {
for ( i = 1; i < results.length; i++ ) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gibson042 changes in this file resulted in the following size diffs compared to if I didn't touch the file:

last run
   raw     gz     br Filename
    +1     -7    +17 dist/jquery.min.js
    +1     -6    -18 dist/jquery.slim.min.js
    +1     -6    +35 dist-module/jquery.module.min.js
    +1     -6    +31 dist-module/jquery.slim.module.min.js

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible it'd go the other way round if we avoided initializers in loops and moved them to declarations, but it's not always possible, as sometimes the same variable is used in multiple loops.

@mgol mgol force-pushed the loops-no-outside-bands branch from c15d743 to b3b1d00 Compare May 11, 2026 22:15
@mgol mgol requested a review from gibson042 May 12, 2026 21:53
Reaching behind array bounds - which is what effectively happens if you check
for `null`/`undefined` value instead of doing a `length` check - can trigger
deopts in various JS engines. Switch to regular `length`-based loops.

In the past, this was impractical as IE <9 used to clobber the `length` property
if an element with the `name="length"` attribute was present, but this is no
longer a concern.
@mgol mgol force-pushed the loops-no-outside-bands branch from b3b1d00 to 4238cfd Compare May 17, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

1 participant