From f5f70343df452f32c6a1ea918bb458d8117706ce Mon Sep 17 00:00:00 2001 From: Liam O'Dea Date: Thu, 20 Aug 2026 23:11:14 +0200 Subject: [PATCH] =?UTF-8?q?perf:=20O(n=C2=B2)=E2=86=92O(n)=20Map=20lookups?= =?UTF-8?q?=20for=20legacy=20reactive=20statements=20(#18602)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/legacy-reactive-map-lookups.md | 5 +++++ packages/svelte/src/compiler/phases/2-analyze/index.js | 3 ++- .../compiler/phases/3-transform/client/transform-client.js | 4 ++-- .../compiler/phases/3-transform/server/transform-server.js | 4 ++-- 4 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 .changeset/legacy-reactive-map-lookups.md diff --git a/.changeset/legacy-reactive-map-lookups.md b/.changeset/legacy-reactive-map-lookups.md new file mode 100644 index 0000000000..ec6f4fbf9d --- /dev/null +++ b/.changeset/legacy-reactive-map-lookups.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +perf: O(n²)→O(n) Map lookups for legacy `$:` reactive statement ordering diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index f9cf2f1d89..1fd83e65b9 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -1318,7 +1318,8 @@ function order_reactive_statements(unsorted_reactive_declarations) { * @returns */ const add_declaration = (node, declaration) => { - if ([...reactive_declarations.values()].includes(declaration)) return; + // Visited set: each ReactiveStatement is stored under exactly one LabeledStatement node + if (reactive_declarations.has(node)) return; for (const binding of declaration.dependencies) { if (declaration.assignments.has(binding)) continue; diff --git a/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js b/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js index 552fe89960..cbb5f2eac7 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js @@ -247,11 +247,11 @@ export function client_component(analysis, options) { } for (const [node] of analysis.reactive_statements) { - const statement = [...state.legacy_reactive_statements].find(([n]) => n === node); + const statement = state.legacy_reactive_statements.get(node); if (statement === undefined) { throw new Error('Could not find reactive statement'); } - instance.body.push(statement[1]); + instance.body.push(statement); } if (analysis.reactive_statements.size > 0) { diff --git a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js index 24ca58bb41..0a533aec37 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js @@ -148,7 +148,7 @@ export function server_component(analysis, options) { const legacy_reactive_declarations = []; for (const [node] of analysis.reactive_statements) { - const statement = [...state.legacy_reactive_statements].find(([n]) => n === node); + const statement = state.legacy_reactive_statements.get(node); if (statement === undefined) { throw new Error('Could not find reactive statement'); } @@ -165,7 +165,7 @@ export function server_component(analysis, options) { } } - instance.body.push(statement[1]); + instance.body.push(statement); } if (legacy_reactive_declarations.length > 0) {