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);