Skip to content

perf(main): only redraw when state changed#428

Merged
agavra merged 1 commit into
agavra:mainfrom
r-vdp:rvdp/skip-idle-redraw
Jun 22, 2026
Merged

perf(main): only redraw when state changed#428
agavra merged 1 commit into
agavra:mainfrom
r-vdp:rvdp/skip-idle-redraw

Conversation

@r-vdp

@r-vdp r-vdp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Following up on the discussion in #394, this is one of the smaller perf
patches I mentioned, with no async/streaming involved.

The main loop currently calls terminal.draw() every 100ms regardless
of whether anything changed. The diff renderer rebuilds every visible
line on each draw, so on large diffs this burns CPU while idle and
ships needless escape sequences over slow links.

This adds a needs_redraw flag set by:

  • any input event (set before event::read() so the many continue
    paths in the key handler still trigger a redraw)
  • the background update check landing
  • message / Ctrl-C-prompt expiry
  • persisted-session reload merging external comments
  • in-flight PR work (forces a redraw each tick so spinners keep
    animating and results paint as soon as they arrive)

When none of those fire, terminal.draw() is skipped entirely.

clear_expired_message() and poll_persisted_session_changes() now
return bool to report whether they touched visible state. The new
has_pending_pr_work() helper just ORs the six PR rx slots.

Tested locally on a ~6k-line diff over a slow ssh hop: idle CPU drops
to zero and ratatui no longer re-emits the cursor-line attrs every
100ms.

The diff renderer rebuilds every visible line on each draw, so the
unconditional redraw every 100ms wastes CPU on idle and ships needless
bytes over slow links. Track a needs_redraw flag set by input events,
the update check, message expiry, persisted-session reloads, and
in-flight PR work, and skip terminal.draw() when nothing changed.

PR spinners keep animating because has_pending_pr_work() forces a
redraw each tick while a forge fetch is in flight.

@agavra agavra left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

@agavra
agavra merged commit a6fafe5 into agavra:main Jun 22, 2026
4 checks passed
@r-vdp
r-vdp deleted the rvdp/skip-idle-redraw branch June 22, 2026 15:55
joaomendoncaa pushed a commit to joaomendoncaa/tuicr that referenced this pull request Jun 26, 2026
The diff renderer rebuilds every visible line on each draw, so the
unconditional redraw every 100ms wastes CPU on idle and ships needless
bytes over slow links. Track a needs_redraw flag set by input events,
the update check, message expiry, persisted-session reloads, and
in-flight PR work, and skip terminal.draw() when nothing changed.

PR spinners keep animating because has_pending_pr_work() forces a
redraw each tick while a forge fetch is in flight.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants