Skip to content

Commit d3cb148

Browse files
authored
perf: better effect pruning (#16625)
* tweak * prune effects where possible * tweak * simplify * simplify * changeset * reset parent if necessary
1 parent acd9eaf commit d3cb148

File tree

2 files changed

+39
-23
lines changed

2 files changed

+39
-23
lines changed

.changeset/tasty-lizards-care.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
perf: prune effects without dependencies

packages/svelte/src/internal/client/reactivity/effects.js

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -133,29 +133,40 @@ function create_effect(type, fn, sync, push = true) {
133133
schedule_effect(effect);
134134
}
135135

136-
// if an effect has no dependencies, no DOM and no teardown function,
137-
// don't bother adding it to the effect tree
138-
var inert =
139-
sync &&
140-
effect.deps === null &&
141-
effect.first === null &&
142-
effect.nodes_start === null &&
143-
effect.teardown === null &&
144-
(effect.f & EFFECT_PRESERVED) === 0;
145-
146-
if (!inert && push) {
147-
if (parent !== null) {
148-
push_effect(effect, parent);
149-
}
136+
if (push) {
137+
/** @type {Effect | null} */
138+
var e = effect;
150139

151-
// if we're in a derived, add the effect there too
140+
// if an effect has already ran and doesn't need to be kept in the tree
141+
// (because it won't re-run, has no DOM, and has no teardown etc)
142+
// then we skip it and go to its child (if any)
152143
if (
153-
active_reaction !== null &&
154-
(active_reaction.f & DERIVED) !== 0 &&
155-
(type & ROOT_EFFECT) === 0
144+
sync &&
145+
e.deps === null &&
146+
e.teardown === null &&
147+
e.nodes_start === null &&
148+
e.first === e.last && // either `null`, or a singular child
149+
(e.f & EFFECT_PRESERVED) === 0
156150
) {
157-
var derived = /** @type {Derived} */ (active_reaction);
158-
(derived.effects ??= []).push(effect);
151+
e = e.first;
152+
}
153+
154+
if (e !== null) {
155+
e.parent = parent;
156+
157+
if (parent !== null) {
158+
push_effect(e, parent);
159+
}
160+
161+
// if we're in a derived, add the effect there too
162+
if (
163+
active_reaction !== null &&
164+
(active_reaction.f & DERIVED) !== 0 &&
165+
(type & ROOT_EFFECT) === 0
166+
) {
167+
var derived = /** @type {Derived} */ (active_reaction);
168+
(derived.effects ??= []).push(e);
169+
}
159170
}
160171
}
161172

@@ -242,7 +253,7 @@ export function inspect_effect(fn) {
242253
*/
243254
export function effect_root(fn) {
244255
Batch.ensure();
245-
const effect = create_effect(ROOT_EFFECT, fn, true);
256+
const effect = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn, true);
246257

247258
return () => {
248259
destroy_effect(effect);
@@ -256,7 +267,7 @@ export function effect_root(fn) {
256267
*/
257268
export function component_root(fn) {
258269
Batch.ensure();
259-
const effect = create_effect(ROOT_EFFECT, fn, true);
270+
const effect = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn, true);
260271

261272
return (options = {}) => {
262273
return new Promise((fulfil) => {
@@ -375,7 +386,7 @@ export function block(fn, flags = 0) {
375386
* @param {boolean} [push]
376387
*/
377388
export function branch(fn, push = true) {
378-
return create_effect(BRANCH_EFFECT, fn, true, push);
389+
return create_effect(BRANCH_EFFECT | EFFECT_PRESERVED, fn, true, push);
379390
}
380391

381392
/**

0 commit comments

Comments
 (0)