- शिप
- 26 अगस्त 2026 को 2:18 am बजे UTC
- लेखक
- kamo
- Commit
- 0aee8b0
Batch 5 of the client-side performance audit. MessageList maps every loaded message to a MessageBubble, and MessageBubble was not memoized. With 300 messages open, one arriving message — or the typing indicator flipping, or a scroll-driven state change — meant 300 bubble renders, each an MUI/Emotion subtree carrying its own Tooltip, Menu and formatter calls, when nothing about the other 299 had changed. Memoizing the bubble alone would not have helped, and that is the part worth writing down. A translated row built `{ ...m, text: ts.translatedText }` inside the map, so it was a fresh object on every render and a shallow comparison could never hit for any translated message — the memo would have looked applied and done nothing. The bubble messages are built once per history/translation change now, and untranslated rows pass the original object straight through, which was already stable. Three more things were being recomputed per render, two of them per row: - `prefers-reduced-motion` was read with a matchMedia call in the render body. It is a useSyncExternalStore subscription now, which is both cheaper and actually live — the old form never noticed a member changing the setting, because nothing re-rendered to re-read it. - The last own non-removed message came from a full `filter` over the history on every render. It only changes when the history does, and a reverse scan finds it without allocating. - The failed-translation tooltip is the same string for every row and was being formatted inside the map. Hoisted. The ResizeObserver is deliberately untouched. Switching it to observe the scroll container instead of the message elements would look like a simplification and would break auto-scroll: the container's own border box does not change when content grows, only its scrollHeight does, and ResizeObserver does not report that. Verified: tsc --noEmit clean over MessageList, MessageBubble and ChatBox with their transitive imports; 63 tests across the chat suites pass, including messageRowIdentity, which asserts a sent message keeps the same row element when the server id replaces the local one — the precise regression a bad memo would cause.