authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-10-07 22:48:56-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-07 22:48:56-07:00
log7873504964c3008ed2a87ada7be62d611e7a281a
tree54834a7780480e72004edd35cad711c0222680be
parent6eed953a060213630af0d7e3cd9a664bd85f7ced
signature Signed by PGP key B5690EEEBB952194

perf(mobile): reduce move-menu index allocations (#16256)


1 files changed, 21 insertions(+), 16 deletions(-)

apps/mobile/src/features/threads/threadOrder.ts+21-16
......@@ -139,22 +139,27 @@ export function computeThreadMoveAvailability(input: {
139139 for (const row of rows) result.set(rowId(row), { canMoveUp: false, canMoveDown: false });
140140 return result;
141141 }
142 const orderedIds = rows.map(rowId);
143 const indexById = new Map(orderedIds.map((id, index) => [id, index] as const));
144 const keysById = new Map(
145 (input.allThreads ?? input.ordered).map(
146 (row) => [rowId(row), rowOrder(row, input.section).key] as const,
147 ),
148 );
149 const writableIds = new Set(
150 (input.allThreads ?? input.ordered)
151 .filter((row) => input.reorderableEnvironmentIds.has(row.environmentId))
152 .map(rowId),
153 );
154 const visibleIds = new Set(orderedIds);
155 const reservedKeys = new Set(
156 [...keysById].flatMap(([id, key]) => (!visibleIds.has(id) && key != null ? [key] : [])),
157 );
142 // Plain loops: this runs per section on every Home rebuild over all shells,
143 // and the map/filter/spread chains it replaces dominated it with garbage.
144 const orderedIds: string[] = [];
145 const indexById = new Map<string, number>();
146 for (const row of rows) {
147 const id = rowId(row);
148 indexById.set(id, orderedIds.length);
149 orderedIds.push(id);
150 }
151 const keysById = new Map<string, string | null>();
152 const writableIds = new Set<string>();
153 for (const row of input.allThreads ?? input.ordered) {
154 const id = rowId(row);
155 keysById.set(id, rowOrder(row, input.section).key);
156 if (input.reorderableEnvironmentIds.has(row.environmentId)) writableIds.add(id);
157 }
158 // Read after the loop so a duplicate id reserves only its final key.
159 const reservedKeys = new Set<string>();
160 keysById.forEach((key, id) => {
161 if (key != null && !indexById.has(id)) reservedKeys.add(key);
162 });
158163 // Mirror of `planPinnedReorder` for adjacent swaps, hoisted so every row is
159164 // answered in O(1) amortized instead of one planner probe per row:
160165 //