Skip to content

fix: coalesce scan() into a single rAF to avoid paint delay on bulk DOM mutations#344

Merged
manuelpuyol merged 4 commits intomainfrom
fix/coalesce-scan-raf
Apr 20, 2026
Merged

fix: coalesce scan() into a single rAF to avoid paint delay on bulk DOM mutations#344
manuelpuyol merged 4 commits intomainfrom
fix/coalesce-scan-raf

Conversation

@alexus37
Copy link
Copy Markdown
Contributor

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 in lazy-define.ts was scheduling a separate requestAnimationFrame callback 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 + requestAnimationFrame deduplication with:

  • A shared Set<ElementLike> that collects pending elements
  • A single requestAnimationFrame timer that processes all pending elements in one callback

This 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.

alexus37 and others added 2 commits April 16, 2026 15:50
…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>
@alexus37 alexus37 marked this pull request as ready for review April 16, 2026 20:41
@alexus37 alexus37 requested a review from a team as a code owner April 16, 2026 20:41
Copilot AI review requested due to automatic review settings April 16, 2026 20:41
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 shared Set of 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

Comment thread src/lazy-define.ts
Comment thread src/lazy-define.ts Outdated
Comment thread test/lazy-define.ts
Copy link
Copy Markdown
Contributor

@manuelpuyol manuelpuyol left a comment

Choose a reason for hiding this comment

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

the copilot comments look valid to me

Comment thread src/lazy-define.ts
@manuelpuyol manuelpuyol merged commit 0b89a6d into main Apr 20, 2026
6 checks passed
@manuelpuyol manuelpuyol deleted the fix/coalesce-scan-raf branch April 20, 2026 13:47
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.

lazy-define scan() schedules per-element requestAnimationFrame, delaying paint on bulk DOM mutations

3 participants