Skip to content

fix: reduce idle TUI CPU usage#36

Merged
osolmaz merged 12 commits into
mainfrom
fix/idle-render-cpu
Jun 9, 2026
Merged

fix: reduce idle TUI CPU usage#36
osolmaz merged 12 commits into
mainfrom
fix/idle-render-cpu

Conversation

@osolmaz

@osolmaz osolmaz commented Jun 8, 2026

Copy link
Copy Markdown
Member

Summary

Idle ghzinga panes could burn CPU just by staying open.
The TUI loop redrew every pass, and each redraw rebuilt GitHub-link regexes while parsing visible text.
This change makes idle panes stay idle, while still redrawing for input, fetch results, loading spinners, control commands, and timed refresh work.

What Changed

The implementation plan is to remove the immediate hot path first, then make the event loop obey the bigger production rule: idle means idle.
This change implements those two steps without changing the rendered UI.

  • Cached the GitHub resource regexes with LazyLock so ResourceId::parse no longer recompiles them during render.
  • Added a dirty-redraw path in the TUI runner so terminal.draw(...) only runs when state changed or a redraw is explicitly needed.
  • Kept loading animations alive only while a resource or file patch fetch is actually loading.
  • Added focused tests for the loading-frame gate so ordinary loaded resources do not advance the spinner path.
  • Refreshed capture manifests after the source commit because the app/rendering tree hash changed but the visual output did not.

Testing

I ran the full local gate from AGENTS.md.
The capture scripts need Python newer than the system /usr/bin/python3, so I ran those with the bundled Python 3.12 interpreter.

  • cargo fmt --check
  • cargo test
  • cargo clippy --all-targets --all-features -- -D warnings
  • npx -y @simpledoc/simpledoc check
  • /Users/onur/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/bin/python3 captures/ghzinga-pr-81834/capture_ghzinga.py --validate-only
  • /Users/onur/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/bin/python3 captures/ghzinga-pr-81834/capture_ghzinga.py --root captures/ghzinga-issue-88499 --mode issue --validate-only
  • /Users/onur/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/bin/python3 captures/ghzinga-pr-81834/capture_mouse_smoke.py --validate-only
  • /Users/onur/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/bin/python3 captures/ghzinga-issue-88499/capture_mouse_smoke.py --validate-only
  • /Users/onur/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/bin/python3 scripts/update-capture-manifests.py --check

Risks

The main risk is missing a redraw after an unusual state change.
The loop now marks redraws for fetch completion, control requests, loading ticks, app events, auto-refresh starts, loading-resource refresh starts, and file-patch load starts.

This does not add a full render-row cache yet.
That can still be a follow-up if a loaded screen with very large visible content is expensive during real user input.

Follow-ups

  • Add an idle CPU regression harness that opens a large fixture, waits without input, and asserts the process stays near zero CPU.

  • Cache parsed link rows by resource/text/width if interactive redraws are still expensive on very large resources.

  • Smoke-tested the patched interactive TUI on fixtures/pr-81834.json for 60 seconds with --refresh-seconds 0; sampled process stayed at 0.0% CPU for all six samples.

@osolmaz

osolmaz commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

Final validation report for head 78294060e84a9b7513372b36b85c505490c4d947.

Implemented idle redraw gating plus cached resource-parse regexes, with follow-up fixes from review for resize redraws, scrollbar fade frames, session-save errors, failed loading placeholders, and resize-batched input.

Validation passed:

  • cargo fmt --check
  • scripts/update-capture-manifests.py --check via bundled Python
  • cargo test (490 unit tests, 15 architecture tests, 9 cli_once tests, doctests)
  • cargo clippy --all-targets --all-features -- -D warnings
  • npx -y @simpledoc/simpledoc check
  • PR/issue capture validation and mouse-smoke validation for both capture sets
  • Final idle CPU smoke: target/debug/gzg --offline-fixture fixtures/pr-81834.json --no-restore --refresh-seconds 0 openclaw/openclaw#81834; sampled six times over 60s, all samples were 0.0% CPU.

Review/CI:

  • Final codex review --base main: no actionable correctness issues found.
  • gh pr view shows no comments or reviews to address.
  • gh pr checks 36 reports no checks configured/reported for this branch.

@osolmaz osolmaz force-pushed the fix/idle-render-cpu branch from 7829406 to 7fe0dae Compare June 9, 2026 03:10
@osolmaz

osolmaz commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

Final validation report for rebased head 141dc91fde518da94589d854d2d1c963b7f02a13.

Resolved the merge conflicts by rebasing fix/idle-render-cpu onto current origin/main (6be5e56), skipped stale manifest-only duplicate commits during the rebase, refreshed capture manifests, and force-pushed with lease. PR is now MERGEABLE / CLEAN.

Implemented idle redraw gating plus cached resource-parse regexes, with follow-up fixes from review for resize redraws, scrollbar fade frames, session-save errors, failed loading placeholders, resize-batched input ordering, and preserving redraw requests after resize-plus-input batches.

Validation passed:

  • cargo fmt --check
  • scripts/update-capture-manifests.py --check via bundled Python
  • cargo check
  • cargo test (491 unit tests, 15 architecture tests, 9 cli_once tests, doctests)
  • cargo clippy --all-targets --all-features -- -D warnings
  • npx -y @simpledoc/simpledoc check
  • scripts/verify-no-png-captures.sh
  • scripts/verify-install.sh
  • sh -n scripts/live-smoke.sh
  • GZG_LIVE_SELF_TEST=1 scripts/live-smoke.sh
  • PR/issue capture validation and mouse-smoke validation for both capture sets
  • Final idle CPU smoke: target/debug/gzg --offline-fixture fixtures/pr-81834.json --no-restore --refresh-seconds 0 openclaw/openclaw#81834; sampled six times over about 60s, all samples were 0.0% CPU.

Review/CI:

  • Final codex review --base origin/main: no actionable correctness issues found.
  • PR comments/reviews checked: no unresolved review comments or new comments to address.
  • GitHub Actions verify: passed in 8m29s.

@osolmaz osolmaz merged commit e19ac50 into main Jun 9, 2026
1 check passed
@osolmaz osolmaz deleted the fix/idle-render-cpu branch June 9, 2026 04:48
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.

1 participant