fix(ui): stabilize virtual list rerender measurements

Keep visible rows mounted during follow-up measurements and clear stale refs so async message rendering no longer flickers or measures detached blocks. Coalesce per-item render notifications so content-heavy rows only trigger one remeasurement per frame.
This commit is contained in:
Shantur Rathore
2026-03-08 18:09:43 +00:00
parent c64a9a03f9
commit b33421a375
3 changed files with 49 additions and 18 deletions

View File

@@ -890,6 +890,23 @@ export default function VirtualFollowList<T>(props: VirtualFollowListProps<T>) {
const suspendMeasurements = () => measurementsSuspended() || !isActive()
const [measureElement, setMeasureElement] = createSignal<HTMLElement | undefined>()
const [contentRenderVersion, setContentRenderVersion] = createSignal(0)
let pendingContentRenderFrame: number | null = null
const notifyItemRendered = () => {
if (pendingContentRenderFrame !== null) return
pendingContentRenderFrame = requestAnimationFrame(() => {
pendingContentRenderFrame = null
setContentRenderVersion((prev) => prev + 1)
})
}
onCleanup(() => {
if (pendingContentRenderFrame !== null) {
cancelAnimationFrame(pendingContentRenderFrame)
pendingContentRenderFrame = null
}
})
return (
<VirtualItem
id={anchorId()}
@@ -930,7 +947,7 @@ export default function VirtualFollowList<T>(props: VirtualFollowListProps<T>) {
{() =>
props.renderItem(item(), index, {
registerMeasureElement: (element) => setMeasureElement(element ?? undefined),
notifyItemRendered: () => setContentRenderVersion((prev) => prev + 1),
notifyItemRendered,
})}
</VirtualItem>
)