Rich Harris 23 hours ago committed by GitHub
commit f53cc95853
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
chore: more efficient effect scheduling

@ -69,6 +69,14 @@ let last_scheduled_effect = null;
let is_flushing = false;
export let is_flushing_sync = false;
/**
* During traversal, this is an array. Newly created effects are (if not immediately
* executed) pushed to this array, rather than going through the scheduling
* rigamarole that would cause another turn of the flush loop.
* @type {Effect[] | null}
*/
export let collected_effects = null;
export class Batch {
/**
* The current values of any sources that are updated in this batch
@ -185,7 +193,7 @@ export class Batch {
this.apply();
/** @type {Effect[]} */
var effects = [];
var effects = (collected_effects = []);
/** @type {Effect[]} */
var render_effects = [];
@ -199,6 +207,8 @@ export class Batch {
// log_inconsistent_branches(root);
}
collected_effects = null;
if (this.#is_deferred()) {
this.#defer_effects(render_effects);
this.#defer_effects(effects);
@ -631,6 +641,7 @@ function flush_effects() {
is_flushing = false;
last_scheduled_effect = null;
collected_effects = null;
if (DEV) {
for (const source of /** @type {Set<Source>} */ (source_stacks)) {
@ -836,14 +847,13 @@ export function schedule_effect(signal) {
// if the effect is being scheduled because a parent (each/await/etc) block
// updated an internal source, or because a branch is being unskipped,
// bail out or we'll cause a second flush
if (
is_flushing &&
effect === active_effect &&
(flags & BLOCK_EFFECT) !== 0 &&
(flags & HEAD_EFFECT) === 0 &&
(flags & REACTION_RAN) !== 0
) {
return;
if (collected_effects !== null && effect === active_effect) {
// in sync mode, render effects run during traversal. in an extreme edge case
// they can be made dirty after they have already been visited, in which
// case we shouldn't bail out
if (async_mode_flag || (signal.f & RENDER_EFFECT) === 0) {
return;
}
}
if ((flags & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) {

@ -40,7 +40,7 @@ import { DEV } from 'esm-env';
import { define_property } from '../../shared/utils.js';
import { get_next_sibling } from '../dom/operations.js';
import { component_context, dev_current_component_function, dev_stack } from '../context.js';
import { Batch, schedule_effect } from './batch.js';
import { Batch, collected_effects, schedule_effect } from './batch.js';
import { flatten, increment_pending } from './async.js';
import { without_reactive_context } from '../dom/elements/bindings/shared.js';
import { set_signal_status } from './status.js';
@ -127,7 +127,11 @@ function create_effect(type, fn, sync) {
throw e;
}
} else if (fn !== null) {
schedule_effect(effect);
if (collected_effects !== null) {
collected_effects.push(effect);
} else {
schedule_effect(effect);
}
}
/** @type {Effect | null} */

Loading…
Cancel
Save