From 5dbd23364bc8ccce9568d74f13e4a3d13534c083 Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Thu, 22 Oct 2026 13:20:02 -0700 Subject: [PATCH] perf(layout): index records once while patching session lists (#31935) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> --- .../workspace-layout-record-patch.ts | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/shared/workspace-layout/workspace-layout-record-patch.ts b/src/shared/workspace-layout/workspace-layout-record-patch.ts index f16cfc8d417..72811e643d7 100644 --- a/src/shared/workspace-layout/workspace-layout-record-patch.ts +++ b/src/shared/workspace-layout/workspace-layout-record-patch.ts @@ -103,8 +103,20 @@ function patchLists( return patched } +function indexRecordsById(list: Json[], idOf: (record: Json) => unknown): Map { + const records = new Map() + for (const record of list) { + const id = idOf(record) + if (!records.has(id)) { + records.set(id, record) + } + } + return records +} + function patchList(stored: Json[], before: Json[], after: Json[], idOf: (record: Json) => unknown) { - const find = (list: Json[], id: unknown) => list.find((record) => idOf(record) === id) + const beforeById = indexRecordsById(before, idOf) + const afterById = indexRecordsById(after, idOf) const result = [...stored] const ids = new Set([...before.map(idOf), ...after.map(idOf)]) const kept = (list: Json[], other: Json[]) => { @@ -114,8 +126,8 @@ function patchList(stored: Json[], before: Json[], after: Json[], idOf: (record: // Records kept their relative order: sort orders changed only to close a removal's gap. const renumberedOnly = sameJson(kept(before, after), kept(after, before)) for (const id of ids) { - const old = find(before, id) - const next = find(after, id) + const old = beforeById.get(id) + const next = afterById.get(id) if (sameJson(old, next)) { continue } @@ -147,10 +159,14 @@ function patchList(stored: Json[], before: Json[], after: Json[], idOf: (record: } // The command reordered its own records: they take `after`'s order in the slots they hold. const placed = new Set(after.map(idOf)) + const resultById = indexRecordsById(result, idOf) const queue = after - .map((record) => result.find((candidate) => idOf(candidate) === idOf(record))) + .map((record) => resultById.get(idOf(record))) .filter((record): record is Json => record !== undefined) - return result.map((record) => (placed.has(idOf(record)) ? (queue.shift() ?? record) : record)) + let nextIndex = 0 + return result.map((record) => + placed.has(idOf(record)) ? (queue[nextIndex++] ?? record) : record + ) } /** After the nearest record that precedes it in `after` and is already in the list. */