perf: 调整虚拟列表配置

pull/49/head
moonrailgun 2 years ago
parent fd8680940b
commit 9160b47343

@ -4,9 +4,9 @@ import type { MessageListProps } from './types';
import {
FollowOutputScalarType,
Virtuoso,
VirtuosoGridHandle,
VirtuosoHandle,
} from 'react-virtuoso';
import { ChatMessage, sharedEvent } from 'tailchat-shared';
import { ChatMessage, sharedEvent, useMemoizedFn } from 'tailchat-shared';
import _last from 'lodash/last';
const PREPEND_OFFSET = 10 ** 7;
@ -21,7 +21,7 @@ const virtuosoStyle: React.CSSProperties = {
*/
export const VirtualizedMessageList: React.FC<MessageListProps> = React.memo(
(props) => {
const listRef = useRef<VirtuosoGridHandle>();
const listRef = useRef<VirtuosoHandle>(null);
const numItemsPrepended = usePrependedMessagesCount(props.messages);
useEffect(() => {
@ -40,7 +40,7 @@ export const VirtualizedMessageList: React.FC<MessageListProps> = React.memo(
};
}, []);
const handleLoadMore = () => {
const handleLoadMore = useMemoizedFn(() => {
if (props.isLoadingMore) {
return;
}
@ -48,31 +48,33 @@ export const VirtualizedMessageList: React.FC<MessageListProps> = React.memo(
if (props.hasMoreMessage) {
props.onLoadMore();
}
};
const followOutput = (isAtBottom: boolean): FollowOutputScalarType => {
if (isAtBottom) {
// 更新最新查看的消息id
const lastMessage = _last(props.messages);
if (lastMessage) {
props.onUpdateReadedMessage(lastMessage._id);
});
const followOutput = useMemoizedFn(
(isAtBottom: boolean): FollowOutputScalarType => {
if (isAtBottom) {
// 更新最新查看的消息id
const lastMessage = _last(props.messages);
if (lastMessage) {
props.onUpdateReadedMessage(lastMessage._id);
}
setTimeout(() => {
// 这里 Virtuoso 有个动态渲染高度的bug, 因此需要异步再次滚动到底部以确保代码功能work
listRef.current?.scrollToIndex({
index:
PREPEND_OFFSET - numItemsPrepended + props.messages.length - 1,
align: 'end',
});
}, 20);
}
setTimeout(() => {
// 这里 Virtuoso 有个动态渲染高度的bug, 因此需要异步再次滚动到底部以确保代码功能work
listRef.current?.scrollToIndex({
index:
PREPEND_OFFSET - numItemsPrepended + props.messages.length - 1,
align: 'end',
});
}, 20);
/**
* ,
*/
return isAtBottom ? 'smooth' : false;
}
/**
* ,
*/
return isAtBottom ? 'smooth' : false;
};
);
const itemContent = (virtuosoIndex: number) => {
const index = virtuosoIndex + numItemsPrepended - PREPEND_OFFSET;
@ -83,16 +85,17 @@ export const VirtualizedMessageList: React.FC<MessageListProps> = React.memo(
return (
<Virtuoso
style={virtuosoStyle}
ref={listRef as any}
ref={listRef}
firstItemIndex={PREPEND_OFFSET - numItemsPrepended}
initialTopMostItemIndex={Math.max(props.messages.length - 1, 0)}
totalCount={props.messages.length}
overscan={20}
overscan={40}
itemContent={itemContent}
alignToBottom={true}
startReached={handleLoadMore}
followOutput={followOutput}
defaultItemHeight={25}
atTopThreshold={100}
atBottomThreshold={40}
/>
);

Loading…
Cancel
Save