diff --git a/.changeset/brown-insects-float.md b/.changeset/brown-insects-float.md new file mode 100644 index 0000000000..58d397b427 --- /dev/null +++ b/.changeset/brown-insects-float.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +perf: speed up $.exclude_from_object diff --git a/packages/svelte/src/compiler/utils/ast.js b/packages/svelte/src/compiler/utils/ast.js index aef6c270a9..1998b0c98e 100644 --- a/packages/svelte/src/compiler/utils/ast.js +++ b/packages/svelte/src/compiler/utils/ast.js @@ -276,15 +276,19 @@ function _extract_paths(assignments = [], param, expression, update_expression, const rest_expression = (object) => { /** @type {ESTree.Expression[]} */ const props = []; + for (const p of param.properties) { if (p.type === 'Property' && p.key.type !== 'PrivateIdentifier') { if (p.key.type === 'Identifier' && !p.computed) { props.push(b.literal(p.key.name)); + } else if (p.key.type === 'Literal') { + props.push(b.literal(String(p.key.value))); } else { - props.push(p.key); + props.push(b.call('String', p.key)); } } } + return b.call('$.exclude_from_object', expression(object), b.array(props)); }; diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index d04d66ba8a..f748fa3993 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -991,12 +991,16 @@ export function update_pre(signal, d = 1) { * @returns {Record} */ export function exclude_from_object(obj, keys) { - obj = { ...obj }; - let key; - for (key of keys) { - delete obj[key]; + /** @type {Record} */ + var result = {}; + + for (var key in obj) { + if (!keys.includes(key)) { + result[key] = obj[key]; + } } - return obj; + + return result; } /** diff --git a/packages/svelte/tests/runtime-legacy/samples/each-block-destructured-object-literal-rest/_config.js b/packages/svelte/tests/runtime-legacy/samples/each-block-destructured-object-literal-rest/_config.js index fc91ce3f6d..3915e2eda3 100644 --- a/packages/svelte/tests/runtime-legacy/samples/each-block-destructured-object-literal-rest/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/each-block-destructured-object-literal-rest/_config.js @@ -9,18 +9,21 @@ export default test({ quote: 'q1', 'wrong-quote': 'wq1', 16: '16', + 17: '17', class: 'class' }, { quote: 'q2', 'wrong-quote': 'wq2', 16: 'sixteen', + 17: 'seventeen', class: 'glass' }, { quote: 'q3', 'wrong-quote': 'wq3', 16: 'seize', + 17: 'dix-sept', class: 'mass' } ] @@ -28,19 +31,19 @@ export default test({ }, html: ` -

Quote: q1, Wrong Quote: wq1, 16: 16

-

Quote: q2, Wrong Quote: wq2, 16: sixteen

-

Quote: q3, Wrong Quote: wq3, 16: seize

+

Quote: q1, Wrong Quote: wq1, 16: 16, 17: 17

+

Quote: q2, Wrong Quote: wq2, 16: sixteen, 17: seventeen

+

Quote: q3, Wrong Quote: wq3, 16: seize, 17: dix-sept

`, test({ assert, component, target }) { component.objectsArray = [ - { quote: 'new-quote', 'wrong-quote': 'wq4', 16: 'ten+six', role: 'role' } + { quote: 'new-quote', 'wrong-quote': 'wq4', 16: 'ten+six', 17: 'ten+seven', role: 'role' } ]; assert.htmlEqual( target.innerHTML, ` -

Quote: new-quote, Wrong Quote: wq4, 16: ten+six

+

Quote: new-quote, Wrong Quote: wq4, 16: ten+six, 17: ten+seven

` ); } diff --git a/packages/svelte/tests/runtime-legacy/samples/each-block-destructured-object-literal-rest/main.svelte b/packages/svelte/tests/runtime-legacy/samples/each-block-destructured-object-literal-rest/main.svelte index 943b3b7940..84a4f1b4fe 100644 --- a/packages/svelte/tests/runtime-legacy/samples/each-block-destructured-object-literal-rest/main.svelte +++ b/packages/svelte/tests/runtime-legacy/samples/each-block-destructured-object-literal-rest/main.svelte @@ -2,6 +2,6 @@ export let objectsArray; -{#each objectsArray as { "quote": quotedProp, "wrong-quote": wrongQuote, 16: sixteen, ...props } } -

Quote: {quotedProp}, Wrong Quote: {wrongQuote}, 16: {sixteen}

+{#each objectsArray as { "quote": quotedProp, "wrong-quote": wrongQuote, 16: sixteen, [10 + 7]: seventeen, ...props }} +

Quote: {quotedProp}, Wrong Quote: {wrongQuote}, 16: {sixteen}, 17: {seventeen}

{/each}