From 2ac73663918645a20e4fe2294ff1073ca306d973 Mon Sep 17 00:00:00 2001 From: PD Shaheed Ali Khan Date: Sat, 22 Aug 2026 02:18:58 +0530 Subject: [PATCH] perf: optimize simple object destructuring in @const tags (#18390) This PR resolves a `TODO` in `ConstTag.js` regarding the optimization of simple object pattern matching cases like `{@const { x } = y}`. --------- Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> --- .changeset/optimize-const-tag.md | 5 ++++ .../src/compiler/phases/1-parse/acorn.js | 2 +- .../3-transform/client/visitors/ConstTag.js | 23 ++++++++++++++----- 3 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 .changeset/optimize-const-tag.md diff --git a/.changeset/optimize-const-tag.md b/.changeset/optimize-const-tag.md new file mode 100644 index 0000000000..90c6a6b5d2 --- /dev/null +++ b/.changeset/optimize-const-tag.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +perf: optimize simple object destructuring in `@const` tags diff --git a/packages/svelte/src/compiler/phases/1-parse/acorn.js b/packages/svelte/src/compiler/phases/1-parse/acorn.js index fb60c228c5..070183f984 100644 --- a/packages/svelte/src/compiler/phases/1-parse/acorn.js +++ b/packages/svelte/src/compiler/phases/1-parse/acorn.js @@ -59,7 +59,7 @@ export function parse(source, comments, typescript, is_script) { return /** @type {Program} */ (ast); } catch (err) { - // TODO the `return` in necessary for TS<7 due to a bug; otherwise + // TODO the `return` is necessary for TS<7 due to a bug; otherwise // the `finally` block is regarded as unreachable return handle_parse_error(err); } finally { diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/ConstTag.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/ConstTag.js index d05d7a8ed9..63c84a507c 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/ConstTag.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/ConstTag.js @@ -45,18 +45,29 @@ export function ConstTag(node, context) { transform }); - // TODO optimise the simple `{ x } = y` case — we can just return `y` - // instead of destructuring it only to return a new object + const is_simple_object_pattern = + declaration.id.type === 'ObjectPattern' && + declaration.id.properties.every( + (p) => + p.type === 'Property' && + !p.computed && + p.key.type === 'Identifier' && + p.value.type === 'Identifier' && + p.key.name === p.value.name + ); + const init = build_expression( { ...context, state: child_state }, declaration.init, node.metadata.expression ); - const block = b.block([ - b.const(/** @type {Pattern} */ (context.visit(declaration.id, child_state)), init), - b.return(b.object(identifiers.map((node) => b.prop('init', node, node)))) - ]); + const block = is_simple_object_pattern + ? b.block([b.return(init)]) + : b.block([ + b.const(/** @type {Pattern} */ (context.visit(declaration.id, child_state)), init), + b.return(b.object(identifiers.map((node) => b.prop('init', node, node)))) + ]); let expression = create_derived(context.state, block, node.metadata.expression.has_await);