perf: 调整虚拟列表配置

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

@ -4,9 +4,9 @@ import type { MessageListProps } from './types';
import { import {
FollowOutputScalarType, FollowOutputScalarType,
Virtuoso, Virtuoso,
VirtuosoGridHandle, VirtuosoHandle,
} from 'react-virtuoso'; } from 'react-virtuoso';
import { ChatMessage, sharedEvent } from 'tailchat-shared'; import { ChatMessage, sharedEvent, useMemoizedFn } from 'tailchat-shared';
import _last from 'lodash/last'; import _last from 'lodash/last';
const PREPEND_OFFSET = 10 ** 7; const PREPEND_OFFSET = 10 ** 7;
@ -21,7 +21,7 @@ const virtuosoStyle: React.CSSProperties = {
*/ */
export const VirtualizedMessageList: React.FC<MessageListProps> = React.memo( export const VirtualizedMessageList: React.FC<MessageListProps> = React.memo(
(props) => { (props) => {
const listRef = useRef<VirtuosoGridHandle>(); const listRef = useRef<VirtuosoHandle>(null);
const numItemsPrepended = usePrependedMessagesCount(props.messages); const numItemsPrepended = usePrependedMessagesCount(props.messages);
useEffect(() => { useEffect(() => {
@ -40,7 +40,7 @@ export const VirtualizedMessageList: React.FC<MessageListProps> = React.memo(
}; };
}, []); }, []);
const handleLoadMore = () => { const handleLoadMore = useMemoizedFn(() => {
if (props.isLoadingMore) { if (props.isLoadingMore) {
return; return;
} }
@ -48,31 +48,33 @@ export const VirtualizedMessageList: React.FC<MessageListProps> = React.memo(
if (props.hasMoreMessage) { if (props.hasMoreMessage) {
props.onLoadMore(); props.onLoadMore();
} }
}; });
const followOutput = (isAtBottom: boolean): FollowOutputScalarType => { const followOutput = useMemoizedFn(
if (isAtBottom) { (isAtBottom: boolean): FollowOutputScalarType => {
// 更新最新查看的消息id if (isAtBottom) {
const lastMessage = _last(props.messages); // 更新最新查看的消息id
if (lastMessage) { const lastMessage = _last(props.messages);
props.onUpdateReadedMessage(lastMessage._id); 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: return isAtBottom ? 'smooth' : false;
PREPEND_OFFSET - numItemsPrepended + props.messages.length - 1,
align: 'end',
});
}, 20);
} }
);
/**
* ,
*/
return isAtBottom ? 'smooth' : false;
};
const itemContent = (virtuosoIndex: number) => { const itemContent = (virtuosoIndex: number) => {
const index = virtuosoIndex + numItemsPrepended - PREPEND_OFFSET; const index = virtuosoIndex + numItemsPrepended - PREPEND_OFFSET;
@ -83,16 +85,17 @@ export const VirtualizedMessageList: React.FC<MessageListProps> = React.memo(
return ( return (
<Virtuoso <Virtuoso
style={virtuosoStyle} style={virtuosoStyle}
ref={listRef as any} ref={listRef}
firstItemIndex={PREPEND_OFFSET - numItemsPrepended} firstItemIndex={PREPEND_OFFSET - numItemsPrepended}
initialTopMostItemIndex={Math.max(props.messages.length - 1, 0)} initialTopMostItemIndex={Math.max(props.messages.length - 1, 0)}
totalCount={props.messages.length} totalCount={props.messages.length}
overscan={20} overscan={40}
itemContent={itemContent} itemContent={itemContent}
alignToBottom={true} alignToBottom={true}
startReached={handleLoadMore} startReached={handleLoadMore}
followOutput={followOutput} followOutput={followOutput}
defaultItemHeight={25} defaultItemHeight={25}
atTopThreshold={100}
atBottomThreshold={40} atBottomThreshold={40}
/> />
); );

Loading…
Cancel
Save