perf(render): fix lazy-render and fold performance for large sessions#393
perf(render): fix lazy-render and fold performance for large sessions#393jensenojs wants to merge 4 commits into
Conversation
c7a6c60 to
a05543b
Compare
|
Thanks for the PR. I will have a look at soon, I will be out for the weekend. So I will look at it at the start of the next week |
|
I want to go out and have fun too. Have a nice weekend! |
|
Awesome, I will do some testing on this throughout the day and let you know. Since this is a significant change in the rendering, I want to test it a little bit. |
|
|
||
| ---@return integer|nil | ||
| local function get_max_rendered_messages() | ||
| local limit = config.ui and config.ui.output and config.ui.output.max_messages |
There was a problem hiding this comment.
I feel that we should combine the max_message behavior with the lazy one, otherwise it might make things confusing. And setting it to nil would essentially disable the lazy rendering ?
There was a problem hiding this comment.
Sorry, I might be a bit busy these two days, and I actually lack some context in understanding the "max_message" feature. I can roughly grasp that the relationship between these two features might be a bit confusing, but I haven't figured it out yet.
For my simple profile, SQLite reading doesn't seem to be the bottleneck. I'll look into why that feature was introduced in the next day or two to make sure I haven't missed any considerations
- Replace cursor+zc fold creation with :{from},{to}fold Ex commands
— avoids cursor-triggered screen redraws (~90ms/fold in large buffers)
- Switch to foldmethod=manual and stay there — prevents foldexpr
recalculation on every buffer line (~4.6s on 87K lines)
- Lazy-render only viewport-sized message count on initial load
- Load more messages on scroll-to-top via WinScrolled autocmd
- Fix lazy_render_count being cleared by M.reset() — read before reset,
persist back to ctx after determining limit
- Debounce WinScrolled load_more callback (150ms) to prevent rapid
re-renders during fast scrolling
- Remove debug vim.notify logging from render paths
Performance: ~36s → ~10ms render time on a 2786-msg/87K-line session.
Closes sudo-tee#392
|
lazy-render is no longer a user setting — it's always on. hidden_count only reflects max_messages truncation now. Behavior changes:
@jemag would be great if you could test this branch — i am not sure if max_messages is still needed for performance on your setup. Rendering should be much faster now. |
1e41de4 to
99e79de
Compare
- Remove opts.lazy: lazy-render is always active as a perf optimization - Decouple hidden_count from lazy-render truncation (only max_messages counts) - Fix cursor jump after load_more: preserve position via anchor message - Add gg keymap: load all messages before jumping to top, so full history is searchable
99e79de to
bdfd9d0
Compare


Problem
2786-message sessions take ~36 seconds to render. Two root causes:
set_folds()usescursor() + normal! zc/zoper fold, each triggering a full-screen redraw (~90ms/fold × 392 folds)_render_full_session_data()renders all messages on initial loadCloses #392
Changes
Fold performance (36s → 3s)
vim.fn.cursor() + normal! zc/zowith:{from},{to}foldand:{from},{to}foldopen!— Ex commands don't move the cursor, zero screen redrawsfoldmethod=manualbefore creating folds and stay there — prevents foldexpr recalculation for every buffer line (~4.6s on 87K lines)E16: Invalid rangeerrorsLazy render (3s → ~10ms)
WinScrolledautocmdopts.lazy = trueexplicit opt-in — tests and headless environments render all messageslazy_render_countbeing cleared byM.reset(): read before reset, persist back toctxafter determining limitWinScrolledload_morecallback (150ms) to prevent rapid re-renders during fast scrollingvim.notifylogging from render pathsPerformance
Measured on a 2786-msg / 87K-line session
Testing
7 new test cases in
tests/unit/renderer_lazy_spec.lua:lazy=falsectx.lazy_render_countis setlazy_render_countincrement across render reset (exposes the core bug)load_more_messagesincrements rendered message countload_more_messagesreturns false when all/no messages loadedAll 110 existing tests pass.