chore: optimise effects that only exist to return a teardown (#11936)

* create teardown effect

* optimise

* changeset

* Update packages/svelte/src/internal/client/reactivity/types.d.ts

Co-authored-by: MotionlessTrain <timothy@familie-de-moor.nl>

* use teardown in bind_property

---------

Co-authored-by: MotionlessTrain <timothy@familie-de-moor.nl>
pull/11963/head
Rich Harris 7 months ago committed by GitHub
parent 76388d042c
commit ddb0bc3888
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
chore: optimise effects that only exist to return a teardown

@ -1,5 +1,5 @@
import { DEV } from 'esm-env';
import { render_effect, effect } from '../../../reactivity/effects.js';
import { render_effect, effect, teardown } from '../../../reactivity/effects.js';
import { stringify } from '../../../render.js';
import { listen_to_event_and_reset_event } from './shared.js';
import * as e from '../../../errors.js';
@ -103,14 +103,12 @@ export function bind_group(inputs, group_index, input, get_value, update) {
}
});
render_effect(() => {
return () => {
teardown(() => {
var index = binding_group.indexOf(input);
if (index !== -1) {
binding_group.splice(index, 1);
}
};
});
effect(() => {
@ -189,6 +187,7 @@ export function bind_files(input, get_value, update) {
listen_to_event_and_reset_event(input, 'change', () => {
update(input.files);
});
render_effect(() => {
input.files = get_value();
});

@ -1,5 +1,5 @@
import { hydrating } from '../../hydration.js';
import { render_effect, effect } from '../../../reactivity/effects.js';
import { render_effect, effect, teardown } from '../../../reactivity/effects.js';
import { listen } from './shared.js';
/** @param {TimeRanges} ranges */
@ -52,7 +52,7 @@ export function bind_current_time(media, get_value, update) {
updating = false;
});
render_effect(() => () => cancelAnimationFrame(raf_id));
teardown(() => cancelAnimationFrame(raf_id));
}
/**

@ -1,4 +1,4 @@
import { render_effect } from '../../../reactivity/effects.js';
import { teardown } from '../../../reactivity/effects.js';
import { get_descriptor } from '../../../utils.js';
/**
@ -15,7 +15,7 @@ export function bind_prop(props, prop, value) {
if (desc && desc.set) {
props[prop] = value;
render_effect(() => () => {
teardown(() => {
props[prop] = null;
});
}

@ -1,4 +1,4 @@
import { render_effect } from '../../../reactivity/effects.js';
import { teardown } from '../../../reactivity/effects.js';
import { add_form_reset_listener } from '../misc.js';
/**
@ -18,12 +18,10 @@ export function listen(target, events, handler, call_handler_immediately = true)
target.addEventListener(name, handler);
}
render_effect(() => {
return () => {
teardown(() => {
for (var name of events) {
target.removeEventListener(name, handler);
}
};
});
}

@ -1,5 +1,4 @@
import { effect, render_effect } from '../../../reactivity/effects.js';
import { untrack } from '../../../runtime.js';
import { effect, teardown } from '../../../reactivity/effects.js';
/**
* Resize observer singleton.
@ -89,7 +88,7 @@ export function bind_resize_observer(element, type, update) {
: resize_observer_device_pixel_content_box;
var unsub = observer.observe(element, /** @param {any} entry */ (entry) => update(entry[type]));
render_effect(() => unsub);
teardown(unsub);
}
/**

@ -1,4 +1,4 @@
import { render_effect } from '../../../reactivity/effects.js';
import { render_effect, teardown } from '../../../reactivity/effects.js';
import { listen } from './shared.js';
/**
@ -57,10 +57,8 @@ export function bind_property(property, event_name, element, set, get) {
// @ts-ignore
if (element === document.body || element === window || element === document) {
render_effect(() => {
return () => {
teardown(() => {
element.removeEventListener(event_name, handler);
};
});
}
}

@ -1,4 +1,4 @@
import { effect, render_effect } from '../../../reactivity/effects.js';
import { effect, render_effect, teardown } from '../../../reactivity/effects.js';
import { listen } from './shared.js';
/**
@ -51,10 +51,8 @@ export function bind_window_scroll(type, get_value, update) {
// Browsers don't fire the scroll event for the initial scroll position when scroll style isn't set to smooth
effect(target_handler);
render_effect(() => {
return () => {
teardown(() => {
removeEventListener('scroll', target_handler);
};
});
}

@ -1,4 +1,4 @@
import { render_effect } from '../../reactivity/effects.js';
import { render_effect, teardown } from '../../reactivity/effects.js';
import { all_registered_events, root_event_handles } from '../../render.js';
import { define_property, is_array } from '../../utils.js';
import { hydrating } from '../hydration.js';
@ -98,10 +98,8 @@ export function event(event_name, dom, handler, capture, passive) {
// @ts-ignore
if (dom === document.body || dom === window || dom === document) {
render_effect(() => {
return () => {
teardown(() => {
dom.removeEventListener(event_name, target_handler, options);
};
});
}
}

@ -30,7 +30,8 @@ import {
ROOT_EFFECT,
EFFECT_TRANSPARENT,
DERIVED,
UNOWNED
UNOWNED,
CLEAN
} from '../constants.js';
import { set } from './sources.js';
import { remove } from '../dom/reconciler.js';
@ -68,7 +69,7 @@ export function push_effect(effect, parent_effect) {
/**
* @param {number} type
* @param {(() => void | (() => void))} fn
* @param {null | (() => void | (() => void))} fn
* @param {boolean} sync
* @returns {import('#client').Effect}
*/
@ -121,7 +122,7 @@ function create_effect(type, fn, sync) {
} finally {
set_is_flushing_effect(previously_flushing_effect);
}
} else {
} else if (fn !== null) {
schedule_effect(effect);
}
@ -144,6 +145,16 @@ export function effect_active() {
return false;
}
/**
* @param {() => void} fn
*/
export function teardown(fn) {
const effect = create_effect(RENDER_EFFECT, null, false);
set_signal_status(effect, CLEAN);
effect.teardown = fn;
return effect;
}
/**
* Internal representation of `$effect(...)`
* @param {() => void | (() => void)} fn
@ -364,7 +375,6 @@ export function destroy_effect(effect, remove_dom = true) {
effect.dom =
effect.deps =
effect.parent =
// @ts-expect-error
effect.fn =
null;
}

@ -18,7 +18,7 @@ export interface Value<V = unknown> extends Signal {
export interface Reaction extends Signal {
/** The reaction function */
fn: Function;
fn: null | Function;
/** Signals that this signal reads from */
deps: null | Value[];
/** First child effect created inside this signal */
@ -40,7 +40,7 @@ export interface Effect extends Reaction {
/** The associated component context */
ctx: null | ComponentContext;
/** The effect function */
fn: () => void | (() => void);
fn: null | (() => void | (() => void));
/** The teardown function returned from the effect function */
teardown: null | (() => void);
/** Transition managers created with `$.transition` */

@ -290,7 +290,7 @@ function handle_error(error, effect, component_context) {
const component_stack = [];
const effect_name = effect.fn.name;
const effect_name = effect.fn?.name;
if (effect_name) {
component_stack.push(effect_name);
@ -358,7 +358,7 @@ export function execute_reaction_fn(signal) {
current_untracking = false;
try {
let res = (0, signal.fn)();
let res = /** @type {Function} */ (0, signal.fn)();
let dependencies = /** @type {import('#client').Value<unknown>[]} **/ (signal.deps);
if (current_dependencies !== null) {
let i;

Loading…
Cancel
Save