Skip to content

Commit 588d636

Browse files
authored
feat: better generated each block code in SSR mode (#13060)
* chore: tidy up each block code * groundwork * cache length * changeset * regenerate
1 parent 3b8801c commit 588d636

File tree

11 files changed

+28
-31
lines changed

11 files changed

+28
-31
lines changed

.changeset/red-maps-nail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
feat: better generated each block code in SSR mode

packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export function EachBlock(node, context) {
147147
// which needs a reference to the index
148148
const index =
149149
each_node_meta.contains_group_binding || !node.index ? each_node_meta.index : b.id(node.index);
150-
const item = each_node_meta.item;
150+
const item = node.context.type === 'Identifier' ? node.context : b.id('$$item');
151151

152152
let uses_index = each_node_meta.contains_group_binding;
153153
let key_uses_index = false;

packages/svelte/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function VariableDeclaration(node, context) {
3232
) {
3333
if (init != null && is_hoisted_function(init)) {
3434
context.state.hoisted.push(
35-
b.declaration('const', declarator.id, /** @type {Expression} */ (context.visit(init)))
35+
b.const(declarator.id, /** @type {Expression} */ (context.visit(init)))
3636
);
3737

3838
continue;
@@ -205,7 +205,7 @@ export function VariableDeclaration(node, context) {
205205

206206
if (init != null && is_hoisted_function(init)) {
207207
context.state.hoisted.push(
208-
b.declaration('const', declarator.id, /** @type {Expression} */ (context.visit(init)))
208+
b.const(declarator.id, /** @type {Expression} */ (context.visit(init)))
209209
);
210210

211211
continue;

packages/svelte/src/compiler/phases/3-transform/server/visitors/EachBlock.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,27 @@ export function EachBlock(node, context) {
1414

1515
const each_node_meta = node.metadata;
1616
const collection = /** @type {Expression} */ (context.visit(node.expression));
17-
const item = each_node_meta.item;
1817
const index =
1918
each_node_meta.contains_group_binding || !node.index ? each_node_meta.index : b.id(node.index);
2019

2120
const array_id = state.scope.root.unique('each_array');
2221
state.init.push(b.const(array_id, b.call('$.ensure_array_like', collection)));
2322

2423
/** @type {Statement[]} */
25-
const each = [b.const(item, b.member(array_id, index, true))];
24+
const each = [b.const(/** @type {Pattern} */ (node.context), b.member(array_id, index, true))];
2625

27-
if (node.context.type !== 'Identifier') {
28-
each.push(b.const(/** @type {Pattern} */ (node.context), item));
29-
}
3026
if (index.name !== node.index && node.index != null) {
3127
each.push(b.let(node.index, index));
3228
}
3329

3430
each.push(.../** @type {BlockStatement} */ (context.visit(node.body)).body);
3531

3632
const for_loop = b.for(
37-
b.let(index, b.literal(0)),
38-
b.binary('<', index, b.member(array_id, 'length')),
33+
b.declaration('let', [
34+
b.declarator(index, b.literal(0)),
35+
b.declarator('$$length', b.member(array_id, 'length'))
36+
]),
37+
b.binary('<', index, b.id('$$length')),
3938
b.update('++', index, false),
4039
b.block(each)
4140
);

packages/svelte/src/compiler/phases/scope.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -547,9 +547,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
547547

548548
binding.metadata = { inside_rest: is_rest_id };
549549
}
550-
if (node.context.type !== 'Identifier') {
551-
scope.declare(b.id('$$item'), 'template', 'synthetic');
552-
}
550+
553551
// Visit to pick up references from default initializers
554552
visit(node.context, { scope });
555553

@@ -583,7 +581,6 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
583581
contains_group_binding: false,
584582
array_name: needs_array_deduplication ? state.scope.root.unique('$$array') : null,
585583
index: scope.root.unique('$$index'),
586-
item: node.context.type === 'Identifier' ? node.context : b.id('$$item'),
587584
declarations: scope.declarations,
588585
is_controlled: false
589586
};

packages/svelte/src/compiler/types/template.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,6 @@ export interface EachBlock extends BaseNode {
405405
/** Set if something in the array expression is shadowed within the each block */
406406
array_name: Identifier | null;
407407
index: Identifier;
408-
item: Identifier;
409408
declarations: Map<string, Binding>;
410409
/**
411410
* Optimization path for each blocks: If the parent isn't a fragment and

packages/svelte/src/compiler/utils/builders.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,27 +176,25 @@ export function logical(operator, left, right) {
176176

177177
/**
178178
* @param {'const' | 'let' | 'var'} kind
179-
* @param {string | ESTree.Pattern} pattern
180-
* @param {ESTree.Expression} [init]
179+
* @param {ESTree.VariableDeclarator[]} declarations
181180
* @returns {ESTree.VariableDeclaration}
182181
*/
183-
export function declaration(kind, pattern, init) {
184-
if (typeof pattern === 'string') pattern = id(pattern);
185-
182+
export function declaration(kind, declarations) {
186183
return {
187184
type: 'VariableDeclaration',
188185
kind,
189-
declarations: [init ? declarator(pattern, init) : declarator(pattern)]
186+
declarations
190187
};
191188
}
192189

193190
/**
194-
* @param {ESTree.Pattern} id
191+
* @param {ESTree.Pattern | string} pattern
195192
* @param {ESTree.Expression} [init]
196193
* @returns {ESTree.VariableDeclarator}
197194
*/
198-
export function declarator(id, init) {
199-
return { type: 'VariableDeclarator', id, init };
195+
export function declarator(pattern, init) {
196+
if (typeof pattern === 'string') pattern = id(pattern);
197+
return { type: 'VariableDeclarator', id: pattern, init };
200198
}
201199

202200
/** @type {ESTree.EmptyStatement} */
@@ -491,7 +489,7 @@ const this_instance = {
491489
* @returns {ESTree.VariableDeclaration}
492490
*/
493491
function let_builder(pattern, init) {
494-
return declaration('let', pattern, init);
492+
return declaration('let', [declarator(pattern, init)]);
495493
}
496494

497495
/**
@@ -500,7 +498,7 @@ function let_builder(pattern, init) {
500498
* @returns {ESTree.VariableDeclaration}
501499
*/
502500
function const_builder(pattern, init) {
503-
return declaration('const', pattern, init);
501+
return declaration('const', [declarator(pattern, init)]);
504502
}
505503

506504
/**
@@ -509,7 +507,7 @@ function const_builder(pattern, init) {
509507
* @returns {ESTree.VariableDeclaration}
510508
*/
511509
function var_builder(pattern, init) {
512-
return declaration('var', pattern, init);
510+
return declaration('var', [declarator(pattern, init)]);
513511
}
514512

515513
/**

packages/svelte/tests/snapshot/samples/each-string-template/_expected/server/index.svelte.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default function Each_string_template($$payload) {
55

66
$$payload.out += `<!--[-->`;
77

8-
for (let $$index = 0; $$index < each_array.length; $$index++) {
8+
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
99
const thing = each_array[$$index];
1010

1111
$$payload.out += `${$.escape(thing)}, `;

packages/svelte/tests/snapshot/samples/inline-module-vars/_expected/client/index.svelte.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ export default function Inline_module_vars($$anchor) {
3030
$.set_attribute(img, "src", __ENHANCED_IMG_5__);
3131
$.reset(picture);
3232
$.append($$anchor, picture);
33-
}
33+
}

packages/svelte/tests/snapshot/samples/inline-module-vars/_expected/server/index.svelte.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ const __ENHANCED_IMG_6__ = "__VITE_ASSET__2AM7_y_f__";
99

1010
export default function Inline_module_vars($$payload) {
1111
$$payload.out += `<picture><source${$.attr("srcset", __ENHANCED_IMG_1__ + " 1440w, " + __ENHANCED_IMG_2__ + " 960w")} type="image/avif"> <source${$.attr("srcset", __ENHANCED_IMG_3__ + " 1440w, " + __ENHANCED_IMG_4__ + " 960w")} type="image/webp"> <source${$.attr("srcset", __ENHANCED_IMG_5__ + " 1440w, " + __ENHANCED_IMG_6__ + " 960w")} type="image/png"> <img${$.attr("src", __ENHANCED_IMG_5__)} alt="production test" width="1440" height="1440"></picture>`;
12-
}
12+
}

packages/svelte/types/index.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1866,7 +1866,6 @@ declare module 'svelte/compiler' {
18661866
/** Set if something in the array expression is shadowed within the each block */
18671867
array_name: Identifier | null;
18681868
index: Identifier;
1869-
item: Identifier;
18701869
declarations: Map<string, Binding>;
18711870
/**
18721871
* Optimization path for each blocks: If the parent isn't a fragment and

0 commit comments

Comments
 (0)