Idle cost: timers and global signals that redraw while nothing happens #233

Closed
opened 2026-10-21 19:08:09 +00:00 by littlefox · 1 comment
Owner

Found in the codebase review (#230, D-058). With NeoKOM open and untouched, it should cost close to nothing. Battery matters on laptops and phones. Today:

  • SEEN_JS (app/src/main_view/mod.rs, #180) runs every 250 ms for as long as the reader is visible, even when nothing moves. Each run does querySelectorAll and getBoundingClientRect on every unread card, which forces layout. Use an IntersectionObserver, plus a timer only while a card is waiting out its second (see #228).
  • CLOCK (app/src/when.rs) ticks every 30 s. ThreadPane and ChannelPostsPane read it at the top, so every 30 s the whole thread or channel (up to hundreds of cards) re-renders to update "5 min sedan".
    • Let only the When labels read it.
    • Tick less often for labels that say hours or days.
  • Presence (app/src/presence.rs) replaces the whole HERE map every 120 s. Every Dot reads HERE, so every dot on screen re-renders even when nobody changed. Write only the entries that changed, or give each person their own signal.
  • Keepalive every 45 s is fine, and needed (#81).

Measure: CPU time of the tab (Chrome performance monitor) and of the desktop process over 10 idle minutes with a long thread open, before and after.

Found in the codebase review (#230, D-058). With NeoKOM open and untouched, it should cost close to nothing. Battery matters on laptops and phones. Today: - **`SEEN_JS`** (`app/src/main_view/mod.rs`, #180) runs every 250 ms for as long as the reader is visible, even when nothing moves. Each run does `querySelectorAll` and `getBoundingClientRect` on every unread card, which forces layout. Use an `IntersectionObserver`, plus a timer only while a card is waiting out its second (see #228). - **`CLOCK`** (`app/src/when.rs`) ticks every 30 s. `ThreadPane` and `ChannelPostsPane` read it at the top, so every 30 s the whole thread or channel (up to hundreds of cards) re-renders to update "5 min sedan". - Let only the `When` labels read it. - Tick less often for labels that say hours or days. - **Presence** (`app/src/presence.rs`) replaces the whole `HERE` map every 120 s. Every `Dot` reads `HERE`, so every dot on screen re-renders even when nobody changed. Write only the entries that changed, or give each person their own signal. - **Keepalive** every 45 s is fine, and needed (#81). Measure: CPU time of the tab (Chrome performance monitor) and of the desktop process over 10 idle minutes with a long thread open, before and after.
Author
Owner

Merged in #271 (main #452 green). Presence dots are now redrawn only when the state or title they show changes (use_memo), so an idle page doesn't redraw every dot on each presence tick. Together with the earlier #226/#228 changes (no CLOCK in the panes, event-driven seen-marking) an idle page is quiet. Verified: full e2e suite on the branch, clippy three ways.

Merged in #271 (main #452 green). Presence dots are now redrawn only when the state or title they show changes (`use_memo`), so an idle page doesn't redraw every dot on each presence tick. Together with the earlier #226/#228 changes (no CLOCK in the panes, event-driven seen-marking) an idle page is quiet. Verified: full e2e suite on the branch, clippy three ways.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
littlefox/neokom#233
No description provided.