fix: coalesce scan() into a single rAF to avoid paint delay on bulk DOM mutations#344
Merged
manuelpuyol merged 4 commits intomainfrom Apr 20, 2026
Merged
fix: coalesce scan() into a single rAF to avoid paint delay on bulk DOM mutations#344manuelpuyol merged 4 commits intomainfrom
manuelpuyol merged 4 commits intomainfrom
Conversation
…OM mutations Replace per-element WeakMap+rAF deduplication with a shared Set of pending elements and a single requestAnimationFrame timer. When many elements are added in one frame (e.g. framework list rendering), only one rAF callback now runs before paint instead of one per element. Fixes #343 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR addresses performance regressions in lazyDefine by coalescing scan() work into a single requestAnimationFrame callback per frame, reducing pre-paint rAF flooding during bulk DOM insertions (Fixes #343).
Changes:
- Replaced per-element rAF deduplication (
WeakMap) with a sharedSetof pending elements and a single rAF timer. - Updated
scan()to process all pending elements in one rAF callback. - Added a test asserting that bulk element insertion does not schedule one rAF per element.
Show a summary per file
| File | Description |
|---|---|
src/lazy-define.ts |
Coalesces multiple scan() calls into a single rAF callback using a shared pending set. |
test/lazy-define.ts |
Adds coverage to ensure bulk-added elements don’t cause excessive rAF scheduling. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 3
manuelpuyol
reviewed
Apr 17, 2026
Contributor
manuelpuyol
left a comment
There was a problem hiding this comment.
the copilot comments look valid to me
manuelpuyol
approved these changes
Apr 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #343
When many elements are added to the DOM in a single frame (e.g. a framework rendering a list), the
scan()function inlazy-define.tswas scheduling a separaterequestAnimationFramecallback for each element. Since all rAF callbacks run before the browser paints, this delayed the first paint proportionally to the number of added elements.Changes
Replaced the per-element
WeakMap+requestAnimationFramededuplication with:Set<ElementLike>that collects pending elementsrequestAnimationFrametimer that processes all pending elements in one callbackThis ensures that no matter how many elements are added in a single frame, only one rAF callback runs before paint.
Testing
Added a test that verifies multiple elements added at once are coalesced into minimal rAF calls rather than one per element. All existing tests continue to pass.