Skip to content

Commit c1d2d4b

Browse files
committed
chore: perf tweaks for actions/styles/classes
- check if we really need to add/remove the class (calling `includes` first is cheaper than always setting/removing it) - check if we really need to update a style (calling `getPropertyValue/setProperty` is expensive) - check if we should call the action's update function (this is not only a perf tweak but also a correctness fix) closes #12652
1 parent d20e064 commit c1d2d4b

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

packages/svelte/src/internal/client/dom/elements/actions.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/** @import { ActionPayload } from '#client' */
22
import { effect, render_effect } from '../../reactivity/effects.js';
3+
import { safe_not_equal } from '../../reactivity/equality.js';
34
import { deep_read_state, untrack } from '../../runtime.js';
45

56
/**
@@ -15,6 +16,8 @@ export function action(dom, action, get_value) {
1516

1617
if (get_value && payload?.update) {
1718
var inited = false;
19+
/** @type {P} */
20+
var prev = /** @type {any} */ ({}); // initialize with something so it's never equal on first run
1821

1922
render_effect(() => {
2023
var value = get_value();
@@ -24,7 +27,8 @@ export function action(dom, action, get_value) {
2427
// together with actions and mutation, it wouldn't notice the change without a deep read.
2528
deep_read_state(value);
2629

27-
if (inited) {
30+
if (inited && safe_not_equal(prev, value)) {
31+
prev = value;
2832
/** @type {Function} */ (payload.update)(value);
2933
}
3034
});

packages/svelte/src/internal/client/dom/elements/class.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,10 @@ function to_class(value) {
107107
*/
108108
export function toggle_class(dom, class_name, value) {
109109
if (value) {
110+
if (dom.classList.contains(class_name)) return;
110111
dom.classList.add(class_name);
111112
} else {
113+
if (!dom.classList.contains(class_name)) return;
112114
dom.classList.remove(class_name);
113115
}
114116
}

packages/svelte/src/internal/client/dom/elements/style.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,19 @@
55
* @param {boolean} [important]
66
*/
77
export function set_style(dom, key, value, important) {
8-
const style = dom.style;
9-
const prev_value = style.getPropertyValue(key);
8+
// @ts-expect-error
9+
var attributes = (dom.__attributes ??= {});
10+
11+
if (attributes['style-' + key] === value) {
12+
return;
13+
}
14+
15+
attributes['style-' + key] = value;
16+
var style = dom.style;
17+
1018
if (value == null) {
11-
if (prev_value !== '') {
12-
style.removeProperty(key);
13-
}
14-
} else if (prev_value !== value) {
19+
style.removeProperty(key);
20+
} else {
1521
style.setProperty(key, value, important ? 'important' : '');
1622
}
1723
}

0 commit comments

Comments
 (0)