perf(tui): build only the visible page of result rows
Scrolling a long results list was laggy: every frame built a table row for every result, and ratatui then drew the forty-odd that fit. At the 10,000-file cap that cost 25-32ms a frame in release (69ms in debug), in attached and standalone mode alike, so a held key stuttered. The pane now slices to the page ratatui would show, by its own rule: stay where the last frame left off, pulled along only as far as keeps the selection in view. The table gets a page-local state and the page start is written back into the real one. The page is counted with the same page_of that PgUp/PgDn use, so paging and drawing agree, and a selection past the end lands on the last row as ratatui put it. Idle frames drop to 1.5ms and a keypress to 0.6ms at the same size, measured live in both modes. ratatui has no lazy rows of its own: the lazy_rows proposal was not merged and moved to the experimental ratatui-table crate, so windowing in the caller is the recommended approach today.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use super::MainTui;
|
||||
use crate::models::{CommandBarMode, FocusedPane, LogView};
|
||||
use crate::ui::pane_block;
|
||||
use crate::ui::page_of;
|
||||
use crate::ui::panes::{
|
||||
InfoSubject, name_end_offset, query_end_offset, selected_transfer,
|
||||
transfer_name_end_offset, upload_display_name,
|
||||
@@ -8,7 +8,7 @@ use crate::ui::panes::{
|
||||
use ratatui::crossterm::event::{
|
||||
KeyCode, KeyEvent, KeyModifiers, MouseButton, MouseEvent, MouseEventKind,
|
||||
};
|
||||
use ratatui::layout::{Position, Rect};
|
||||
use ratatui::layout::Position;
|
||||
use ratatui::widgets::TableState;
|
||||
|
||||
const NAME_SCROLL_STEP: isize = 8;
|
||||
@@ -575,16 +575,6 @@ impl MainTui {
|
||||
}
|
||||
}
|
||||
|
||||
/// Rows a list in `area` shows at once, less the `chrome` rows above it: a
|
||||
/// table header, a popup's tab bar and compose line. At least one, so a page
|
||||
/// key always moves, even before the first draw.
|
||||
fn page_of(area: Option<Rect>, chrome: u16) -> usize {
|
||||
area.map_or(0, |area| {
|
||||
usize::from(pane_block(false).inner(area).height.saturating_sub(chrome))
|
||||
})
|
||||
.max(1)
|
||||
}
|
||||
|
||||
/// A move over a whole list at once: to either end, or by a number of rows
|
||||
/// (negative is up).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
|
||||
Reference in New Issue
Block a user