Skip to content

Commit cb12431

Browse files
trueadmRich-Harris
andauthored
chore: bring back recursive processing of effects (#12861)
* chore: bring back recursive processing of effects * Update packages/svelte/src/internal/client/runtime.js Co-authored-by: Rich Harris <[email protected]> --------- Co-authored-by: Rich Harris <[email protected]>
1 parent 43679b8 commit cb12431

File tree

1 file changed

+50
-60
lines changed

1 file changed

+50
-60
lines changed

packages/svelte/src/internal/client/runtime.js

Lines changed: 50 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,53 @@ export function schedule_effect(signal) {
571571
current_queued_root_effects.push(effect);
572572
}
573573

574+
/**
575+
* @param {Effect} effect
576+
* @param {Effect[]} effects
577+
*/
578+
function process_effect_children(effect, effects) {
579+
var current = effect.first;
580+
581+
while (current !== null) {
582+
var next = current.next;
583+
process_effect(current, effects);
584+
current = next;
585+
}
586+
}
587+
588+
/**
589+
* @param {Effect} effect
590+
* @param {Effect[]} effects
591+
*/
592+
function process_effect(effect, effects) {
593+
var flags = effect.f;
594+
// TODO: we probably don't need to check for destroyed as it shouldn't be encountered?
595+
var is_active = (flags & (DESTROYED | INERT)) === 0;
596+
var is_branch = (flags & BRANCH_EFFECT) !== 0;
597+
var is_clean = (flags & CLEAN) !== 0;
598+
599+
// Skip this branch if it's clean
600+
if (is_active && (!is_branch || !is_clean)) {
601+
if (is_branch) {
602+
set_signal_status(effect, CLEAN);
603+
}
604+
605+
if ((flags & RENDER_EFFECT) !== 0) {
606+
if (!is_branch && check_dirtiness(effect)) {
607+
update_effect(effect);
608+
}
609+
610+
process_effect_children(effect, effects);
611+
} else if ((flags & EFFECT) !== 0) {
612+
if (is_branch || is_clean) {
613+
process_effect_children(effect, effects);
614+
} else {
615+
effects.push(effect);
616+
}
617+
}
618+
}
619+
}
620+
574621
/**
575622
*
576623
* This function both runs render effects and collects user effects in topological order
@@ -583,70 +630,13 @@ export function schedule_effect(signal) {
583630
* @returns {void}
584631
*/
585632
function process_effects(effect, collected_effects) {
586-
var current_effect = effect.first;
633+
/** @type {Effect[]} */
587634
var effects = [];
588-
589-
main_loop: while (current_effect !== null) {
590-
var flags = current_effect.f;
591-
// TODO: we probably don't need to check for destroyed as it shouldn't be encountered?
592-
var is_active = (flags & (DESTROYED | INERT)) === 0;
593-
var is_branch = flags & BRANCH_EFFECT;
594-
var is_clean = (flags & CLEAN) !== 0;
595-
var child = current_effect.first;
596-
597-
// Skip this branch if it's clean
598-
if (is_active && (!is_branch || !is_clean)) {
599-
if (is_branch) {
600-
set_signal_status(current_effect, CLEAN);
601-
}
602-
603-
if ((flags & RENDER_EFFECT) !== 0) {
604-
if (!is_branch && check_dirtiness(current_effect)) {
605-
update_effect(current_effect);
606-
// Child might have been mutated since running the effect
607-
child = current_effect.first;
608-
}
609-
610-
if (child !== null) {
611-
current_effect = child;
612-
continue;
613-
}
614-
} else if ((flags & EFFECT) !== 0) {
615-
if (is_branch || is_clean) {
616-
if (child !== null) {
617-
current_effect = child;
618-
continue;
619-
}
620-
} else {
621-
effects.push(current_effect);
622-
}
623-
}
624-
}
625-
var sibling = current_effect.next;
626-
627-
if (sibling === null) {
628-
let parent = current_effect.parent;
629-
630-
while (parent !== null) {
631-
if (effect === parent) {
632-
break main_loop;
633-
}
634-
var parent_sibling = parent.next;
635-
if (parent_sibling !== null) {
636-
current_effect = parent_sibling;
637-
continue main_loop;
638-
}
639-
parent = parent.parent;
640-
}
641-
}
642-
643-
current_effect = sibling;
644-
}
645-
635+
process_effect_children(effect, effects);
646636
// We might be dealing with many effects here, far more than can be spread into
647637
// an array push call (callstack overflow). So let's deal with each effect in a loop.
648638
for (var i = 0; i < effects.length; i++) {
649-
child = effects[i];
639+
var child = effects[i];
650640
collected_effects.push(child);
651641
process_effects(child, collected_effects);
652642
}

0 commit comments

Comments
 (0)