Skip to content

Commit 0240ec4

Browse files
committed
reuse lookup
1 parent e7a1c3a commit 0240ec4

File tree

2 files changed

+13
-16
lines changed

2 files changed

+13
-16
lines changed

packages/svelte/src/internal/client/dom/blocks/each.js

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ function pause_effects(effects, controlled_anchor, callback) {
9191
*/
9292
export function each(anchor, flags, get_collection, get_key, render_fn, fallback_fn = null) {
9393
/** @type {import('#client').EachState} */
94-
var state = { flags, next: null };
94+
var state = { flags, items: new Map(), next: null };
9595

9696
var is_controlled = (flags & EACH_IS_CONTROLLED) !== 0;
9797

@@ -117,8 +117,6 @@ export function each(anchor, flags, get_collection, get_key, render_fn, fallback
117117
? []
118118
: Array.from(collection);
119119

120-
var keys = get_key === null ? array : array.map(get_key);
121-
122120
var length = array.length;
123121

124122
// If we are working with an array that isn't proxied or frozen, then remove strict equality and ensure the items
@@ -171,7 +169,10 @@ export function each(anchor, flags, get_collection, get_key, render_fn, fallback
171169
}
172170

173171
child_anchor = hydrate_anchor(child_anchor);
174-
item = create_item(child_anchor, prev, null, array[i], keys?.[i], i, render_fn, flags);
172+
var value = array[i];
173+
var key = get_key(value, i);
174+
item = create_item(child_anchor, prev, null, value, key, i, render_fn, flags);
175+
state.items.set(key, item);
175176
child_anchor = /** @type {Comment} */ (child_anchor.nextSibling);
176177

177178
prev = item;
@@ -225,12 +226,10 @@ export function each(anchor, flags, get_collection, get_key, render_fn, fallback
225226
function reconcile(array, state, anchor, render_fn, flags, get_key) {
226227
var is_animated = (flags & EACH_IS_ANIMATED) !== 0;
227228

229+
var items = state.items;
228230
var first = state.next;
229231
var current = first;
230232

231-
/** @type {Map<any, import('#client').EachItem>} */
232-
var lookup = new Map();
233-
234233
/** @type {Set<import('#client').EachItem>} */
235234
var seen = new Set();
236235

@@ -255,18 +254,11 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
255254
/** @type {import('#client').EachItem | undefined} */
256255
var item;
257256

258-
while (current) {
259-
lookup.set(current.k, current);
260-
current = current.next;
261-
}
262-
263-
current = first;
264-
265257
if (is_animated) {
266258
for (let i = 0; i < array.length; i += 1) {
267259
value = array[i];
268260
key = get_key(value, i);
269-
item = lookup.get(key);
261+
item = items.get(key);
270262

271263
if (item !== undefined) {
272264
item.a?.measure();
@@ -278,7 +270,7 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
278270
for (let i = 0; i < array.length; i += 1) {
279271
value = array[i];
280272
key = get_key(value, i);
281-
item = lookup.get(key);
273+
item = items.get(key);
282274

283275
if (item === undefined) {
284276
prev = create_item(
@@ -292,6 +284,8 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
292284
flags
293285
);
294286

287+
items.set(key, prev);
288+
295289
matched = [];
296290
stashed = [];
297291

@@ -369,6 +363,7 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
369363
null,
370364
() => {
371365
for (const item of to_destroy) {
366+
items.delete(item.k);
372367
link(item.prev, item.next);
373368
}
374369
}

packages/svelte/src/internal/client/types.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ export type Dom = TemplateNode | TemplateNode[];
5050
export type EachState = {
5151
/** flags */
5252
flags: number;
53+
/** a key -> item lookup */
54+
items: Map<any, EachItem>;
5355
/** head of the linked list of items */
5456
next: EachItem | null;
5557
};

0 commit comments

Comments
 (0)