Skip to content

Commit 8dba71d

Browse files
committed
mostly working
1 parent 2e22c43 commit 8dba71d

File tree

1 file changed

+45
-6
lines changed
  • packages/svelte/src/internal/client/dom/blocks

1 file changed

+45
-6
lines changed

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

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,12 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
268268
}
269269
}
270270

271+
/** @type {import('#client').EachItem[]} */
272+
var matched = [];
273+
274+
/** @type {import('#client').EachItem[]} */
275+
var stashed = [];
276+
271277
for (let i = 0; i < array.length; i += 1) {
272278
var value = array[i];
273279
var key = get_key(value, i);
@@ -294,19 +300,52 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
294300

295301
if (item !== current) {
296302
if (seen.has(item)) {
297-
move(item, prev, current ? get_first_child(current) : anchor);
303+
if (matched.length < stashed.length) {
304+
// more efficient to move later items to the front
305+
prev = stashed[0].prev;
306+
const a = get_first_child(stashed[0]);
307+
308+
for (var thing of matched) {
309+
move(thing, prev, a);
310+
prev = thing;
311+
}
312+
313+
for (var thing of stashed) {
314+
seen.delete(thing);
315+
}
316+
317+
current = stashed[0];
318+
i -= 1;
319+
320+
matched = [];
321+
stashed = [];
322+
} else {
323+
// more efficient to move earlier items to the back
324+
const a = current ? get_first_child(current) : anchor;
325+
326+
lookup.delete(key);
327+
move(item, prev, a);
328+
}
298329
} else {
299330
while (current && current.k !== key) {
300331
seen.add(current);
332+
stashed.push(current);
301333
current = current.next;
302334
}
335+
336+
if (current) {
337+
matched.push(current);
338+
current = item.next;
339+
prev = item;
340+
lookup.delete(key);
341+
}
303342
}
343+
} else {
344+
matched.push(current);
345+
current = item.next;
346+
prev = item;
347+
lookup.delete(key);
304348
}
305-
306-
lookup.delete(key);
307-
308-
prev = item;
309-
current = item.next;
310349
}
311350

312351
const to_destroy = Array.from(lookup.values());

0 commit comments

Comments
 (0)