perf: better effect pruning (#16625)

* tweak

* prune effects where possible

* tweak

* simplify

* simplify

* changeset

* reset parent if necessary
pull/16642/head
Rich Harris 2 weeks ago committed by GitHub
parent acd9eaf2ec
commit d3cb1482fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
perf: prune effects without dependencies

@ -133,29 +133,40 @@ function create_effect(type, fn, sync, push = true) {
schedule_effect(effect); schedule_effect(effect);
} }
// if an effect has no dependencies, no DOM and no teardown function, if (push) {
// don't bother adding it to the effect tree /** @type {Effect | null} */
var inert = var e = effect;
sync &&
effect.deps === null &&
effect.first === null &&
effect.nodes_start === null &&
effect.teardown === null &&
(effect.f & EFFECT_PRESERVED) === 0;
if (!inert && push) {
if (parent !== null) {
push_effect(effect, parent);
}
// if we're in a derived, add the effect there too // if an effect has already ran and doesn't need to be kept in the tree
// (because it won't re-run, has no DOM, and has no teardown etc)
// then we skip it and go to its child (if any)
if ( if (
active_reaction !== null && sync &&
(active_reaction.f & DERIVED) !== 0 && e.deps === null &&
(type & ROOT_EFFECT) === 0 e.teardown === null &&
e.nodes_start === null &&
e.first === e.last && // either `null`, or a singular child
(e.f & EFFECT_PRESERVED) === 0
) { ) {
var derived = /** @type {Derived} */ (active_reaction); e = e.first;
(derived.effects ??= []).push(effect); }
if (e !== null) {
e.parent = parent;
if (parent !== null) {
push_effect(e, parent);
}
// if we're in a derived, add the effect there too
if (
active_reaction !== null &&
(active_reaction.f & DERIVED) !== 0 &&
(type & ROOT_EFFECT) === 0
) {
var derived = /** @type {Derived} */ (active_reaction);
(derived.effects ??= []).push(e);
}
} }
} }
@ -242,7 +253,7 @@ export function inspect_effect(fn) {
*/ */
export function effect_root(fn) { export function effect_root(fn) {
Batch.ensure(); Batch.ensure();
const effect = create_effect(ROOT_EFFECT, fn, true); const effect = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn, true);
return () => { return () => {
destroy_effect(effect); destroy_effect(effect);
@ -256,7 +267,7 @@ export function effect_root(fn) {
*/ */
export function component_root(fn) { export function component_root(fn) {
Batch.ensure(); Batch.ensure();
const effect = create_effect(ROOT_EFFECT, fn, true); const effect = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn, true);
return (options = {}) => { return (options = {}) => {
return new Promise((fulfil) => { return new Promise((fulfil) => {
@ -375,7 +386,7 @@ export function block(fn, flags = 0) {
* @param {boolean} [push] * @param {boolean} [push]
*/ */
export function branch(fn, push = true) { export function branch(fn, push = true) {
return create_effect(BRANCH_EFFECT, fn, true, push); return create_effect(BRANCH_EFFECT | EFFECT_PRESERVED, fn, true, push);
} }
/** /**

Loading…
Cancel
Save