lazy mount message blocks

This commit is contained in:
Shantur Rathore
2025-12-09 01:04:49 +00:00
parent 7aba3c1221
commit 7996228327
2 changed files with 33 additions and 55 deletions

View File

@@ -8,11 +8,9 @@ export function getMessageAnchorId(messageId: string) {
}
const VIRTUAL_ITEM_MARGIN_PX = 800
const ESTIMATED_MESSAGE_HEIGHT = 320
const INITIAL_FORCE_MIN_ITEMS = 12
const INITIAL_FORCE_OVERSCAN = 6
interface MessageBlockListProps {
instanceId: string
sessionId: string
store: () => InstanceMessageStore
@@ -31,50 +29,10 @@ interface MessageBlockListProps {
}
export default function MessageBlockList(props: MessageBlockListProps) {
const [initialForceActive, setInitialForceActive] = createSignal(true)
const [initialForceInitialized, setInitialForceInitialized] = createSignal(false)
const [initialForceStartIndex, setInitialForceStartIndex] = createSignal(0)
const [, setInitialForceRemaining] = createSignal(0)
createEffect(() => {
props.instanceId
props.sessionId
setInitialForceActive(true)
setInitialForceInitialized(false)
setInitialForceStartIndex(0)
setInitialForceRemaining(0)
})
createEffect(() => {
if (!initialForceActive() || initialForceInitialized()) return
const ids = props.messageIds()
if (ids.length === 0) return
const viewportHeight = props.scrollContainer()?.clientHeight ?? (typeof window !== "undefined" ? window.innerHeight : 800)
const estimatedCount = Math.min(
ids.length,
Math.max(INITIAL_FORCE_MIN_ITEMS, Math.ceil(viewportHeight / ESTIMATED_MESSAGE_HEIGHT) + INITIAL_FORCE_OVERSCAN),
)
setInitialForceStartIndex(Math.max(0, ids.length - estimatedCount))
setInitialForceRemaining(estimatedCount)
setInitialForceInitialized(true)
})
return (
<>
<Index each={props.messageIds()}>
{(messageId) => {
const messageIndex = () => props.messageIndexMap().get(messageId()) ?? 0
const forceVisible = () => initialForceActive() && messageIndex() >= initialForceStartIndex()
const handleMeasured = () => {
if (!forceVisible()) return
setInitialForceRemaining((value) => {
const next = value > 0 ? value - 1 : 0
if (next === 0) {
setInitialForceActive(false)
}
return next
})
}
return (
<VirtualItem
id={getMessageAnchorId(messageId())}
@@ -83,8 +41,6 @@ export default function MessageBlockList(props: MessageBlockListProps) {
threshold={VIRTUAL_ITEM_MARGIN_PX}
placeholderClass="message-stream-placeholder"
virtualizationEnabled={() => !props.loading}
forceVisible={forceVisible}
onMeasured={handleMeasured}
>
<MessageBlock