bubbletea
bubbletea copied to clipboard
Optimize refresh on remote server or slow network
On the device with slow refresh rate, every "View()" will cause a blink since it re-renders the whole area or fullscreen. Do you have any plans to only re-render the the part it changes in order to avoid those blinks? (just like Kindle devices, not every page-up/page-down will cause a whole refresh)
Yes, we definitely have plans to improve this! No specific timeline at the moment, but optimizing rendering is a big one for us.
What's your specific use case? Bubble Tea does have a high performance API for scrolling which the Viewport component can take advantage of (see Model.HighPerformanceRendering
). For an example of this is production check out Glow. For the lower level scrolling API in Bubble Tea see ScrollDown
, ScrollUp
and SyncScrollArea
.
I love your user icon, btw.
@meowgorithm currently, bubbletea has HUGE troubles with rendering, honestly. when you try to update screen you have two ways:
Way №1) use ansi codes in result of View()
function. Optimized? Hell yes, ansi codes can move your cursor, set terminal size, color, sometimes font, etc. But we have main trouble: we don't know where cursor is! That's really big trouble, and cause this, we can't use this way.
Way №2) rerender all app. But, emmm, you know, that's worst idea, we need avoid it.
So. what's my solution:
What if we replace View() string
to something like Render(ctx bt.ViewContext) []bt.RenderCommands
? Name of these types can be any, you choose, but focus on my idea: Models (bubbles, apps, widgets, or which the hell name does them have) are not just render functions, they are objects, which can talk with bubbletea framework: they can ask about them render environment (ViewContext
) and send to renderer commands (RenderCommands
, like "Hey, bubbletea renderer, can you draw a square from x1y1 to x2y2 with amazing #0ff
to #0b8
gradient from left to right? Thanks!"). Also, instead of copypasting some cool features (gradient rendering, stylesheets, etc), we can implement it only in renderer! And that could be even more cool
I'd prefer not to introduce lower-level drawing commands just yet. Bubble Tea actually currently has some low-level scrolling commands for performance reasons, and they're much harder to work with compared to versus just describing a UI with View() string
.
One of the primary design goals in Bubble Tea was to remove the need for the user to worry about rendering logic. View() string
is the basic expression of that: a user can describe a view in its entirety, and then Bubble Tea handles the painting logic. The renderer actually does have some rendering optimizations, and while it's not as efficient as something lower level, and in many cases it's more than fast enough.
All that said we are exploring a notion of a more advanced, AST-based renderer where one can return a layout and the renderer repaints only things that have changed.
flutter also allow users don't care about how widgets render, however even flutter have build context. i'll try to make a few solutions and come back
Just a note that #95, which was merged about a week ago, contains an optimization where only changed lines are repainted. We have further optimizations planned, but this should improve rendering over the network quite a bit.
Just a datapoint: #95 seems like it definitely helps! I was using HighPerformanceRendering
with a viewport whose content repainted every 100ms to update a progress UI, and there was very noticeable flickering even for simple one-line changes (e.g. an increasing duration on every repaint).
Turning HighPerformanceRendering
off and removing the viewport.Sync()
s dramatically reduced flickering. Now it only flickers when the viewport auto-scrolls to show new lines of output, since all the lines above it have to be redrawn, but that's more tolerable.