Skip to content

Batch reactivity triggers in a microtask scheduler - #818

Open
wouterlucas wants to merge 1 commit into
masterfrom
async-reactivity-scheduler
Open

wouterlucas wants to merge 1 commit into
masterfrom
async-reactivity-scheduler

Conversation

@wouterlucas

Copy link
Copy Markdown
Contributor

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:

  • New src/lib/reactivity/scheduler.js (flushJobs / queueJob / invalidateJob). Queue is ordered parents-before-children by job.id via sorted insertion on enqueue (no Array.sort pass); equal ids stay FIFO.
  • trigger() queues instead of running inline; removeEffects() also purges queued jobs so destroyed/for-loop effects never run stale.
  • Component $nextTick flushes 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).
  • Unit tests and the renderComponent fixture 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).

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
@github-actions

Copy link
Copy Markdown

Test Results: ✅ PASSED

Run at: 2026-10-25T20:21:20.781Z

Summary:
passed: 1563 failed: 0 of 1563 tests

@github-actions

Copy link
Copy Markdown

Benchmark comparison

Timing Change
Synchronous generation -99.95%
Total time to idle +0.43%

Negative means faster. Informational results; small changes can be measurement noise.

Full report · Workflow run

Head: c9f3603cbf4b · Base: d38eef864ec5

This branch has not been deployed

No deployments
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.

1 participant