Skip to content

Is the full-frame redraw intentional, or is a diff path planned? #125

Description

@erxonxi

Hi! First off, zigzag is great — we built an agent TUI on it and the component set plus the Elm model made it a real pleasure to work with.

While using it we ran into high CPU and input lag when an animated spinner runs alongside streaming text on a tall screen. We traced it to Program.render(): on any view change it rewrites the whole visible frame (cursor-home + every line), so a single spinner character triggers a full-screen redraw ~10×/sec. We've fixed it on our side (caching the rendered regions so view() stays cheap, and slowing the spinner), so this isn't blocking us.

But we noticed src/terminal/screen.zig has a complete cell-level renderDiff() that Program never calls — the render loop works on raw view strings instead. That made us curious:

  • Is the full-frame redraw a deliberate choice (it's nicely self-healing under synchronized output), with renderDiff just a standalone utility?
  • Or was a diff-based render path something you'd planned, and renderDiff is waiting to be wired in?
  • Could reducing per-frame output help SGR mouse sequences leak as garbage characters during rapid scrolling #123 (SGR garbage during fast scrolling)?

For context, Bubble Tea — which zigzag is inspired by — does line-level diffing in its renderer, so it felt natural to ask.

If it's a direction you'd want, we'd genuinely be happy to help — e.g. open a PR for an opt-in line-level diff (skip unchanged lines), with tests, zero new deps, matching your style. And if the full-frame approach is intentional, that's a perfectly good answer — mostly we wanted to understand the thinking behind the unwired renderDiff.

Thanks for the library!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions