Repository navigation
Batch reactivity triggers in a microtask scheduler - #818
Open
wouterlucas wants to merge 1 commit into
Open
wouterlucas wants to merge 1 commit into
wouterlucas wants to merge 1 commit into
Conversation
Replace synchronous per-set effect runs with an async batch scheduler ported from Vue2 queueWatcher/flushSchedulerQueue: trigger() queues effects (deduped, parent-before-child by job id via sorted insert) and flushes once per microtask, so N synchronous state writes produce 1 run instead of N. - Add src/lib/reactivity/scheduler.js (flushJobs/queueJob/invalidateJob) - trigger() queues instead of running inline; removeEffects() purges queued jobs for destroyed effects - $nextTick flushes pending effects before scheduling its timeout, so callbacks observe committed state without relying on host microtask/macrotask pump ordering - Tests/fixture flush synchronously (flushJobs) to stay deterministic
Test Results: ✅ PASSEDRun at: 2026-10-25T20:21:20.781Z Summary: |
Benchmark comparison
Negative means faster. Informational results; small changes can be measurement noise. Head: |
This branch has not been deployed
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.
Replaces synchronous per-set effect runs with an async batch scheduler ported from Vue2's queueWatcher/flushSchedulerQueue.
Problem: every reactive set ran all dependent effects inline, so N synchronous state writes produced N effect runs (and N renderer writes) instead of 1.
What changed:
src/lib/reactivity/scheduler.js(flushJobs/queueJob/invalidateJob). Queue is ordered parents-before-children byjob.idvia sorted insertion on enqueue (noArray.sortpass); equal ids stay FIFO.trigger()queues instead of running inline;removeEffects()also purges queued jobs so destroyed/for-loop effects never run stale.$nextTickflushes pending effects before scheduling its timeout, so callbacks observe committed state without relying on host microtask/macrotask pump ordering (matters on QuickJS/older Chrome targets).renderComponentfixture flush synchronously (flushJobs) to stay deterministic.Verification: eslint clean, full suite 1524/1524 pass. Follows repo prettier config and the perf rules (for-loops only, explicit comparisons, no spread in hot paths).