Three more rounds of lag removal aimed at heavy upload sessions:
- main-process debugLog() was doing fs.appendFileSync on every call
and was firing hundreds of times per second during busy uploads
(progress transitions, unhandled rejection traces, folder-monitor
events). Replaced with an in-memory buffer flushed every 500ms via
async appendFile — the main event loop is no longer blocked per
line. Buffered entries flush synchronously on before-quit.
- the renderer's 'RX upload-progress' / 'RX upload-stats' listeners
were emitting one IPC roundtrip per event. For 20 concurrent jobs
that's 80 IPC messages/sec just for logging. They now skip the
debug call on the hot 'uploading' tick and only log transitions.
- _onQueueScroll now coalesces scroll events via requestAnimationFrame
so a fast trackpad fling triggers one virtual render per frame
instead of one per wheel event.
- maybeAddSessionFile switched from O(n) sessionFilesData.some() dedup
to an O(1) Set lookup keyed on (link, filename, host). Adding 1000
results to an already-populated panel drops from ~500ms to <5ms.
Three more wins on top of the previous pass:
- sortQueueJobs memoizes the result for static sort keys
(filename, host, size) — these don't change during upload, so
every 200ms progress render now reuses the same sorted array
instead of running an O(n log n) Collator compare.
- _computeQueueStats caches within a single tick via queueMicrotask.
updateStatusBar + updateStatsPanel are always called back-to-back
and now share one queue scan instead of running two.
- _updateRowInPlace writes DOM values only when they actually
changed. Idle/queued/done rows (the majority) incur zero DOM
mutations per progress tick.