feat(lazy loading): Implement virtual list with virtua (#241)
### Summary of Improvements This PR replaces the custom `IntersectionObserver`-based virtualization with the `virtua` library to significantly improve rendering performance and UI responsiveness. ### 🚀 Performance Results Verified using `session-performance.test.ts`: - **Rendering**: 2000 messages rendered in **16.90ms**. - **Huge Conversation**: 10,000 messages processed in **0.80ms**. - **Session Switching**: Average switch time reduced to **0.58ms** (virtually zero lag). ### 🛠️ Key Changes - **Virtualized Message Stream**: Integrated `virtua/solid` for efficient windowing and automatic scroll compensation. - **Floating Scroll Controls**: Applied `position: absolute` and `pointer-events: none` to the list controls to ensure scroll-to-top/bottom buttons float correctly over the message area without blocking interactions. - **Package Synchronization**: Updated `virtua` and SDK dependencies, with a fully synchronized `package-lock.json` for stable builds. ### 🎥 UI Verification https://github.com/user-attachments/assets/24e483a3-8be6-4ac4-a431-d719f2015f4e - **Smooth Scrolling**: Verified that rendering gaps are eliminated during fast scrolls. - **Position Retention**: Scroll positions are preserved when switching between sessions. > [!NOTE] > Detailed performance gains and layout fixes are isolated to the `virtua` implementation and core package updates, following the requested cleanup. --------- Co-authored-by: Shantur Rathore <i@shantur.com>
This commit is contained in:
committed by
GitHub
parent
68407a01a4
commit
313e82880b
@@ -1,39 +1,58 @@
|
||||
.message-stream {
|
||||
@apply flex-1 min-h-0 overflow-y-auto flex flex-col gap-0.5;
|
||||
background-color: var(--surface-base);
|
||||
color: inherit;
|
||||
/* Prevent browser scroll anchoring fighting our virtualization compensation. */
|
||||
overflow-anchor: none;
|
||||
}
|
||||
|
||||
.message-stream-block {
|
||||
.virtual-follow-list-shell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.0625rem;
|
||||
|
||||
contain: layout paint style;
|
||||
}
|
||||
|
||||
.virtual-item-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.virtual-item-placeholder,
|
||||
.message-stream {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
background-color: var(--surface-base);
|
||||
color: inherit;
|
||||
|
||||
/* Scrolling optimizations */
|
||||
overscroll-behavior-y: contain;
|
||||
/* Prevents scroll chaining to parent elements */
|
||||
will-change: scroll-position;
|
||||
/* GPU acceleration hint for smoother scrolling */
|
||||
-webkit-overflow-scrolling: touch;
|
||||
/* Momentum scrolling on iOS */
|
||||
|
||||
/* Prevent browser scroll anchoring fighting our virtualization compensation. */
|
||||
overflow-anchor: none;
|
||||
|
||||
/* Scrollbar styling */
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.virtual-follow-list-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
/* Ensure it doesn't affect layout at all */
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.virtual-follow-list-overlay > * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.virtual-follow-list-controls-container {
|
||||
position: absolute;
|
||||
bottom: calc(var(--space-md) + env(safe-area-inset-bottom, 0px));
|
||||
right: var(--space-md);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.message-stream-placeholder {
|
||||
display: block;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.virtual-item-content {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.virtual-item-content-hidden {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user