chore: improve each block fast-path heuristic (#9855)

* chore: improve each block fast-path heuristic

* chore: improve each block fast-path heuristic
pull/9861/head
Dominic Gannaway 11 months ago committed by GitHub
parent 3a9b1436e8
commit cb529fc666
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
chore: improve each block fast-path heuristic

@ -2137,11 +2137,10 @@ export const template_visitors = {
} }
// The runtime needs to know what kind of each block this is in order to optimize for the // The runtime needs to know what kind of each block this is in order to optimize for the
// immutable + key==entry case. In that case, the item doesn't need to be reactive, because // key === item (we avoid extra allocations). In that case, the item doesn't need to be reactive.
// the array as a whole is immutable, so if something changes, it either has to recreate the // We can guarantee this by knowing that in order for the item of the each block to change, they
// array or use nested reactivity through runes. // would need to mutate the key/item directly in the array. Given that in runes mode we use ===
// TODO this feels a bit "hidden performance boost"-style, investigate if there's a way // equality, we can apply a fast-path (as long as the index isn't reactive).
// to make this apply in more cases
let each_type = 0; let each_type = 0;
if ( if (
@ -2149,21 +2148,22 @@ export const template_visitors = {
(node.key.type !== 'Identifier' || !node.index || node.key.name !== node.index) (node.key.type !== 'Identifier' || !node.index || node.key.name !== node.index)
) { ) {
each_type |= EACH_KEYED; each_type |= EACH_KEYED;
// If there's a destructuring, then we likely need the generated $$index
if (node.index || node.context.type !== 'Identifier') {
each_type |= EACH_INDEX_REACTIVE;
}
if ( if (
context.state.analysis.runes &&
node.key.type === 'Identifier' && node.key.type === 'Identifier' &&
node.context.type === 'Identifier' && node.context.type === 'Identifier' &&
node.context.name === node.key.name && node.context.name === node.key.name &&
context.state.options.immutable (each_type & EACH_INDEX_REACTIVE) === 0
) { ) {
// Fast-path // Fast-path for when the key === item
each_item_is_reactive = false; each_item_is_reactive = false;
} else { } else {
each_type |= EACH_ITEM_REACTIVE; each_type |= EACH_ITEM_REACTIVE;
} }
// If there's a destructuring, then we likely need the generated $$index
if (node.index || node.context.type !== 'Identifier') {
each_type |= EACH_INDEX_REACTIVE;
}
} else { } else {
each_type |= EACH_ITEM_REACTIVE; each_type |= EACH_ITEM_REACTIVE;
} }
@ -2289,7 +2289,7 @@ export const template_visitors = {
) )
: b.literal(null); : b.literal(null);
const key_function = const key_function =
node.key && (each_type & 1) /* EACH_ITEM_REACTIVE */ !== 0 node.key && ((each_type & EACH_ITEM_REACTIVE) !== 0 || context.state.options.dev)
? b.arrow( ? b.arrow(
[node.context.type === 'Identifier' ? node.context : b.id('$$item')], [node.context.type === 'Identifier' ? node.context : b.id('$$item')],
b.block( b.block(

Loading…
Cancel
Save