forked from Keelrleek/Harbor
Opening the chat froze the machine: the log rendered all ~800 loaded messages (1.1 M characters, ~10,000 nodes, a 440,000 px column) and rebuilt the whole log on every new message, receipt change and mark refresh - about 1.8 s of blocked main thread each time. Now: - the log keeps the newest 150 rows; "Load earlier" adds 150 more (from memory, then the server) and keeps the reader's place; switching person or thread starts again at 150 - new messages are appended; a changed receipt, pin, correction or answer repaints only its row - off-screen rows skip layout and paint (content-visibility); the Intl date formatters are made once - polls go through every(): no overlapping requests; while the tab is hidden messages poll every 10 s (sound and notifications still work), people every 60 s, the overview every 30 s, and the marks refresh and board panels pause - removed the backdrop-filter blurs on the sidebar, top bar and composer, and the live dot's endless box-shadow animation (now opacity) Measured: forced full render 1,600-1,850 ms -> 16-21 ms (hidden pane, render + layout); load long task 1,806 ms -> 56 ms; DOM 13,318 -> 5,282 nodes (log 9,870 -> 1,806); a new message appends 2 nodes with no long task; hidden-tab traffic ~37 requests / ~2 MB per 30 s -> 4 requests / 156 KB.