Skip to content

Commit

Permalink
chore: simplify flushing (#15348)
Browse files Browse the repository at this point in the history
* this appears to be unnecessary

* DRY out

* this doesnt appear to do anything useful

* simplify

* remove unused if block

* simplify, make non-recursive

* unused

* DRY

* simplify

* tidy up

* simplify

* changeset

* unused

* Revert "changeset"

This reverts commit 946e00d.

* make flush_sync non-recursive

* fix flushSync types

* fix

* unused

* simplify

* tidy up

* tidy up

* present unnecessary microtasks, avoid flushing if no function provided

* simplify
  • Loading branch information
Rich-Harris authored Feb 24, 2025
1 parent 7958eb7 commit 51337f2
Show file tree
Hide file tree
Showing 25 changed files with 182 additions and 233 deletions.
5 changes: 5 additions & 0 deletions .changeset/violet-camels-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: update types and inline docs for flushSync
4 changes: 2 additions & 2 deletions benchmarking/benchmarks/reactivity/kairo/kairo_avoidable.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ function setup() {
return {
destroy,
run() {
$.flush_sync(() => {
$.flush(() => {
$.set(head, 1);
});
assert($.get(computed5) === 6);
for (let i = 0; i < 1000; i++) {
$.flush_sync(() => {
$.flush(() => {
$.set(head, i);
});
assert($.get(computed5) === 6);
Expand Down
4 changes: 2 additions & 2 deletions benchmarking/benchmarks/reactivity/kairo/kairo_broad.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ function setup() {
return {
destroy,
run() {
$.flush_sync(() => {
$.flush(() => {
$.set(head, 1);
});
counter = 0;
for (let i = 0; i < 50; i++) {
$.flush_sync(() => {
$.flush(() => {
$.set(head, i);
});
assert($.get(last) === i + 50);
Expand Down
4 changes: 2 additions & 2 deletions benchmarking/benchmarks/reactivity/kairo/kairo_deep.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ function setup() {
return {
destroy,
run() {
$.flush_sync(() => {
$.flush(() => {
$.set(head, 1);
});
counter = 0;
for (let i = 0; i < iter; i++) {
$.flush_sync(() => {
$.flush(() => {
$.set(head, i);
});
assert($.get(current) === len + i);
Expand Down
4 changes: 2 additions & 2 deletions benchmarking/benchmarks/reactivity/kairo/kairo_diamond.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ function setup() {
return {
destroy,
run() {
$.flush_sync(() => {
$.flush(() => {
$.set(head, 1);
});
assert($.get(sum) === 2 * width);
counter = 0;
for (let i = 0; i < 500; i++) {
$.flush_sync(() => {
$.flush(() => {
$.set(head, i);
});
assert($.get(sum) === (i + 1) * width);
Expand Down
4 changes: 2 additions & 2 deletions benchmarking/benchmarks/reactivity/kairo/kairo_mux.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ function setup() {
destroy,
run() {
for (let i = 0; i < 10; i++) {
$.flush_sync(() => {
$.flush(() => {
$.set(heads[i], i);
});
assert($.get(splited[i]) === i + 1);
}
for (let i = 0; i < 10; i++) {
$.flush_sync(() => {
$.flush(() => {
$.set(heads[i], i * 2);
});
assert($.get(splited[i]) === i * 2 + 1);
Expand Down
4 changes: 2 additions & 2 deletions benchmarking/benchmarks/reactivity/kairo/kairo_repeated.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ function setup() {
return {
destroy,
run() {
$.flush_sync(() => {
$.flush(() => {
$.set(head, 1);
});
assert($.get(current) === size);
counter = 0;
for (let i = 0; i < 100; i++) {
$.flush_sync(() => {
$.flush(() => {
$.set(head, i);
});
assert($.get(current) === i * size);
Expand Down
4 changes: 2 additions & 2 deletions benchmarking/benchmarks/reactivity/kairo/kairo_triangle.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ function setup() {
destroy,
run() {
const constant = count(width);
$.flush_sync(() => {
$.flush(() => {
$.set(head, 1);
});
assert($.get(sum) === constant);
counter = 0;
for (let i = 0; i < 100; i++) {
$.flush_sync(() => {
$.flush(() => {
$.set(head, i);
});
assert($.get(sum) === constant - width + i * width);
Expand Down
4 changes: 2 additions & 2 deletions benchmarking/benchmarks/reactivity/kairo/kairo_unstable.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ function setup() {
return {
destroy,
run() {
$.flush_sync(() => {
$.flush(() => {
$.set(head, 1);
});
assert($.get(current) === 40);
counter = 0;
for (let i = 0; i < 100; i++) {
$.flush_sync(() => {
$.flush(() => {
$.set(head, i);
});
}
Expand Down
4 changes: 2 additions & 2 deletions benchmarking/benchmarks/reactivity/mol_bench.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ function setup() {
*/
run(i) {
res.length = 0;
$.flush_sync(() => {
$.flush(() => {
$.set(B, 1);
$.set(A, 1 + i * 2);
});
$.flush_sync(() => {
$.flush(() => {
$.set(A, 2 + i * 2);
$.set(B, 2);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ export function client_component(analysis, options) {

const setter = b.set(key, [
b.stmt(b.call(b.id(name), b.id('$$value'))),
b.stmt(b.call('$.flush_sync'))
b.stmt(b.call('$.flush'))
]);

if (analysis.runes && binding.initial) {
Expand Down
12 changes: 2 additions & 10 deletions packages/svelte/src/index-client.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @import { ComponentContext, ComponentContextLegacy } from '#client' */
/** @import { EventDispatcher } from './index.js' */
/** @import { NotFunction } from './internal/types.js' */
import { flush_sync, untrack } from './internal/client/runtime.js';
import { untrack } from './internal/client/runtime.js';
import { is_array } from './internal/shared/utils.js';
import { user_effect } from './internal/client/index.js';
import * as e from './internal/client/errors.js';
Expand Down Expand Up @@ -206,15 +206,7 @@ function init_update_callbacks(context) {
return (l.u ??= { a: [], b: [], m: [] });
}

/**
* Synchronously flushes any pending state changes and those that result from it.
* @param {() => void} [fn]
* @returns {void}
*/
export function flushSync(fn) {
flush_sync(fn);
}

export { flushSync } from './internal/client/runtime.js';
export { getContext, getAllContexts, hasContext, setContext } from './internal/client/context.js';
export { hydrate, mount, unmount } from './internal/client/render.js';
export { tick, untrack } from './internal/client/runtime.js';
Expand Down
4 changes: 2 additions & 2 deletions packages/svelte/src/internal/client/dom/blocks/await.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DEV } from 'esm-env';
import { is_promise } from '../../../shared/utils.js';
import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js';
import { internal_set, mutable_source, source } from '../../reactivity/sources.js';
import { flush_sync, set_active_effect, set_active_reaction } from '../../runtime.js';
import { flushSync, set_active_effect, set_active_reaction } from '../../runtime.js';
import { hydrate_next, hydrate_node, hydrating } from '../hydration.js';
import { queue_micro_task } from '../task.js';
import { UNINITIALIZED } from '../../../../constants.js';
Expand Down Expand Up @@ -105,7 +105,7 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) {

// without this, the DOM does not update until two ticks after the promise
// resolves, which is unexpected behaviour (and somewhat irksome to test)
flush_sync();
flushSync();
}
}
}
Expand Down
47 changes: 22 additions & 25 deletions packages/svelte/src/internal/client/dom/task.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,58 +6,55 @@ const request_idle_callback =
? (/** @type {() => void} */ cb) => setTimeout(cb, 1)
: requestIdleCallback;

let is_micro_task_queued = false;
let is_idle_task_queued = false;

/** @type {Array<() => void>} */
let current_queued_micro_tasks = [];
let micro_tasks = [];

/** @type {Array<() => void>} */
let current_queued_idle_tasks = [];
let idle_tasks = [];

function process_micro_tasks() {
is_micro_task_queued = false;
const tasks = current_queued_micro_tasks.slice();
current_queued_micro_tasks = [];
function run_micro_tasks() {
var tasks = micro_tasks;
micro_tasks = [];
run_all(tasks);
}

function process_idle_tasks() {
is_idle_task_queued = false;
const tasks = current_queued_idle_tasks.slice();
current_queued_idle_tasks = [];
function run_idle_tasks() {
var tasks = idle_tasks;
idle_tasks = [];
run_all(tasks);
}

/**
* @param {() => void} fn
*/
export function queue_micro_task(fn) {
if (!is_micro_task_queued) {
is_micro_task_queued = true;
queueMicrotask(process_micro_tasks);
if (micro_tasks.length === 0) {
queueMicrotask(run_micro_tasks);
}
current_queued_micro_tasks.push(fn);

micro_tasks.push(fn);
}

/**
* @param {() => void} fn
*/
export function queue_idle_task(fn) {
if (!is_idle_task_queued) {
is_idle_task_queued = true;
request_idle_callback(process_idle_tasks);
if (idle_tasks.length === 0) {
request_idle_callback(run_idle_tasks);
}
current_queued_idle_tasks.push(fn);

idle_tasks.push(fn);
}

/**
* Synchronously run any queued tasks.
*/
export function flush_tasks() {
if (is_micro_task_queued) {
process_micro_tasks();
if (micro_tasks.length > 0) {
run_micro_tasks();
}
if (is_idle_task_queued) {
process_idle_tasks();

if (idle_tasks.length > 0) {
run_idle_tasks();
}
}
2 changes: 1 addition & 1 deletion packages/svelte/src/internal/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export {
get,
safe_get,
invalidate_inner_signals,
flush_sync,
flushSync as flush,
tick,
untrack,
exclude_from_object,
Expand Down
8 changes: 0 additions & 8 deletions packages/svelte/src/internal/client/reactivity/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@ import {
update_effect,
get,
is_destroying_effect,
is_flushing_effect,
remove_reactions,
schedule_effect,
set_active_reaction,
set_is_destroying_effect,
set_is_flushing_effect,
set_signal_status,
untrack,
skip_reaction,
untracking
} from '../runtime.js';
import {
Expand Down Expand Up @@ -118,17 +115,12 @@ function create_effect(type, fn, sync, push = true) {
}

if (sync) {
var previously_flushing_effect = is_flushing_effect;

try {
set_is_flushing_effect(true);
update_effect(effect);
effect.f |= EFFECT_RAN;
} catch (e) {
destroy_effect(effect);
throw e;
} finally {
set_is_flushing_effect(previously_flushing_effect);
}
} else if (fn !== null) {
schedule_effect(effect);
Expand Down
26 changes: 10 additions & 16 deletions packages/svelte/src/internal/client/reactivity/sources.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import {
derived_sources,
set_derived_sources,
check_dirtiness,
set_is_flushing_effect,
is_flushing_effect,
untracking
} from '../runtime.js';
import { equals, safe_equals } from './equality.js';
Expand Down Expand Up @@ -202,22 +200,18 @@ export function internal_set(source, value) {

if (DEV && inspect_effects.size > 0) {
const inspects = Array.from(inspect_effects);
var previously_flushing_effect = is_flushing_effect;
set_is_flushing_effect(true);
try {
for (const effect of inspects) {
// Mark clean inspect-effects as maybe dirty and then check their dirtiness
// instead of just updating the effects - this way we avoid overfiring.
if ((effect.f & CLEAN) !== 0) {
set_signal_status(effect, MAYBE_DIRTY);
}
if (check_dirtiness(effect)) {
update_effect(effect);
}

for (const effect of inspects) {
// Mark clean inspect-effects as maybe dirty and then check their dirtiness
// instead of just updating the effects - this way we avoid overfiring.
if ((effect.f & CLEAN) !== 0) {
set_signal_status(effect, MAYBE_DIRTY);
}
if (check_dirtiness(effect)) {
update_effect(effect);
}
} finally {
set_is_flushing_effect(previously_flushing_effect);
}

inspect_effects.clear();
}
}
Expand Down
Loading

0 comments on commit 51337f2

Please sign in to comment.