Skip to content

Commit 5d616d1

Browse files
committed
perf: optimize non-reactive if statements
1 parent 501f415 commit 5d616d1

File tree

5 files changed

+87
-3
lines changed

5 files changed

+87
-3
lines changed

.changeset/khaki-jobs-smoke.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: optimize non-reactive if statements

packages/svelte/src/compiler/phases/3-transform/client/visitors/IfBlock.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,25 @@ import * as b from '../../../../utils/builders.js';
88
* @param {ComponentContext} context
99
*/
1010
export function IfBlock(node, context) {
11-
context.state.template.push_quasi('<!>');
11+
const { state } = context;
1212

1313
const consequent = /** @type {BlockStatement} */ (context.visit(node.consequent));
1414

15+
// compile to if rather than $.if for non-reactive if statements
16+
// NOTE: this only handles expressions that are simple identifiers and doesn't handle else/elseif yet
17+
if (state.analysis.runes && node.test.type === 'Identifier' && !(node.alternate || node.elseif)) {
18+
const binding = state.scope.owner(node.test.name)?.declarations.get(node.test.name);
19+
if (binding?.kind === 'normal') {
20+
consequent.body.unshift(b.var(b.id('$$anchor'), state.node));
21+
state.init.push(b.if(node.test, consequent));
22+
return;
23+
}
24+
}
25+
26+
state.template.push_quasi('<!>');
27+
1528
const args = [
16-
context.state.node,
29+
state.node,
1730
b.thunk(/** @type {Expression} */ (context.visit(node.test))),
1831
b.arrow([b.id('$$anchor')], consequent)
1932
];
@@ -51,5 +64,5 @@ export function IfBlock(node, context) {
5164
args.push(b.literal(true));
5265
}
5366

54-
context.state.init.push(b.stmt(b.call('$.if', ...args)));
67+
state.init.push(b.stmt(b.call('$.if', ...args)));
5568
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import "svelte/internal/disclose-version";
2+
import * as $ from "svelte/internal/client";
3+
4+
var root = $.template(` <!>`, 1);
5+
6+
export default function Non_reactive_control_structures($$anchor) {
7+
const a = true;
8+
let b = true;
9+
var fragment = root();
10+
var node = $.first_child(fragment);
11+
12+
if (a) {
13+
var $$anchor = node;
14+
var text = $.text("hello");
15+
16+
$.append($$anchor, text);
17+
}
18+
19+
var node_1 = $.sibling(node, 2);
20+
21+
$.if(node_1, () => b, ($$anchor) => {
22+
var text_1 = $.text("world");
23+
24+
$.append($$anchor, text_1);
25+
});
26+
27+
$.append($$anchor, fragment);
28+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as $ from "svelte/internal/server";
2+
3+
export default function Non_reactive_control_structures($$payload) {
4+
const a = true;
5+
let b = true;
6+
7+
if (a) {
8+
$$payload.out += "<!--[-->";
9+
$$payload.out += `hello`;
10+
} else {
11+
$$payload.out += "<!--[!-->";
12+
}
13+
14+
$$payload.out += `<!--]--> `;
15+
16+
if (b) {
17+
$$payload.out += "<!--[-->";
18+
$$payload.out += `world`;
19+
} else {
20+
$$payload.out += "<!--[!-->";
21+
}
22+
23+
$$payload.out += `<!--]-->`;
24+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<svelte:options runes={true} />
2+
3+
<script>
4+
const a = true;
5+
let b = $state(true);
6+
</script>
7+
8+
{#if a}
9+
hello
10+
{/if}
11+
12+
{#if b}
13+
world
14+
{/if}

0 commit comments

Comments
 (0)