'优化FlatList性能,改进上传管理和增强错误处理'

This commit is contained in:
Junhui Chen 2025-07-24 00:16:27 +08:00
parent 83d713c38c
commit a18c2f7592
7 changed files with 51 additions and 20 deletions

View File

@ -109,6 +109,9 @@ const MemoList = () => {
ItemSeparatorComponent={() => ( ItemSeparatorComponent={() => (
<View style={styles.separator} /> <View style={styles.separator} />
)} )}
getItemLayout={(data, index) => (
{ length: 80, offset: 80 * index, index }
)}
renderItem={({ item }) => ( renderItem={({ item }) => (
<TouchableOpacity <TouchableOpacity
style={styles.memoItem} style={styles.memoItem}

View File

@ -56,12 +56,13 @@ export default function OwnerPage() {
}) })
} }
// 设计轮询获取数量统计 // 设计轮询获取数量统计
// useEffect(() => { useEffect(() => {
// const interval = setInterval(() => { // 将轮询间隔增加到5秒减少服务器压力和电池消耗
// getCountData(); const interval = setInterval(() => {
// }, 1000); getCountData();
// return () => clearInterval(interval); }, 5000);
// }, []); return () => clearInterval(interval);
}, []);
// 初始化获取用户信息 // 初始化获取用户信息
useEffect(() => { useEffect(() => {
@ -107,6 +108,10 @@ export default function OwnerPage() {
<Ranking data={userInfoDetails.title_rankings} /> <Ranking data={userInfoDetails.title_rankings} />
</View> </View>
} }
// 优化性能:添加 getItemLayout
getItemLayout={(data, index) => (
{ length: 1000, offset: 1000 * index, index }
)}
/> />
{/* 设置弹窗 - 使用条件渲染避免层级冲突 */} {/* 设置弹窗 - 使用条件渲染避免层级冲突 */}
{modalVisible && ( {modalVisible && (

View File

@ -0,0 +1 @@
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==

View File

@ -84,6 +84,7 @@ const MessageItem = ({ t, insets, item, sessionId, setModalVisible, modalVisible
borderRadius: 12, borderRadius: 12,
}} }}
resizeMode="cover" resizeMode="cover"
loadingIndicatorSource={require('@/assets/images/png/placeholder.png')}
/> />
</Pressable> </Pressable>
))} ))}
@ -218,6 +219,7 @@ const MessageItem = ({ t, insets, item, sessionId, setModalVisible, modalVisible
style={detailsStyles.image} style={detailsStyles.image}
onError={(error) => console.log('Image load error:', error.nativeEvent.error)} onError={(error) => console.log('Image load error:', error.nativeEvent.error)}
onLoad={() => console.log('Image loaded successfully')} onLoad={() => console.log('Image loaded successfully')}
loadingIndicatorSource={require('@/assets/images/png/placeholder.png')}
/> />
<TouchableOpacity <TouchableOpacity
style={[detailsStyles.circleMarker, selectedImages.includes(item?.id || item?.video?.id) ? detailsStyles.circleMarkerSelected : ""]} style={[detailsStyles.circleMarker, selectedImages.includes(item?.id || item?.video?.id) ? detailsStyles.circleMarkerSelected : ""]}

View File

@ -33,12 +33,25 @@ function ChatComponent({ userMessages, sessionId, setSelectedImages, selectedIma
// 自动滚动到底部 // 自动滚动到底部
useEffect(() => { useEffect(() => {
if (userMessages.length > 0) { if (userMessages.length > 0) {
setTimeout(() => { // 延迟滚动以确保渲染完成
const timer = setTimeout(() => {
flatListRef.current?.scrollToEnd({ animated: true }); flatListRef.current?.scrollToEnd({ animated: true });
}, 100); }, 150);
return () => clearTimeout(timer);
} }
}, [userMessages]); }, [userMessages]);
// 优化 FlatList 性能 - 提供 getItemLayout 方法
const getItemLayout = useCallback((data: Message[] | null | undefined, index: number) => {
// 假设每个消息项的高度大约为 100可根据实际情况调整
const averageItemHeight = 100;
return {
length: averageItemHeight,
offset: averageItemHeight * index,
index,
};
}, []);
return ( return (
<SafeAreaView className='flex-1'> <SafeAreaView className='flex-1'>
<FlatList <FlatList
@ -52,6 +65,7 @@ function ChatComponent({ userMessages, sessionId, setSelectedImages, selectedIma
updateCellsBatchingPeriod={50} updateCellsBatchingPeriod={50}
initialNumToRender={10} initialNumToRender={10}
windowSize={11} windowSize={11}
getItemLayout={getItemLayout}
renderItem={({ item }) => MessageItem({ t, setSelectedImages, selectedImages, insets, item, sessionId, modalVisible, setModalVisible, setModalDetailsVisible, modalDetailsVisible })} renderItem={({ item }) => MessageItem({ t, setSelectedImages, selectedImages, insets, item, sessionId, modalVisible, setModalVisible, setModalDetailsVisible, modalDetailsVisible })}
/> />
</SafeAreaView> </SafeAreaView>

View File

@ -216,26 +216,30 @@ export const ImagesUploader: React.FC<ImagesuploaderProps> = ({
const CONCURRENCY_LIMIT = 3; const CONCURRENCY_LIMIT = 3;
const results: UploadResult[] = []; const results: UploadResult[] = [];
// 分批处理资源 // 分批处理资源,优化并发处理
for (let i = 0; i < assets.length; i += CONCURRENCY_LIMIT) { const processBatch = async (batch: ImagePicker.ImagePickerAsset[]) => {
const batch = assets.slice(i, i + CONCURRENCY_LIMIT);
// 并行处理当前批次的所有资源
const batchResults = await Promise.allSettled( const batchResults = await Promise.allSettled(
batch.map(asset => processSingleAsset(asset)) batch.map(asset => processSingleAsset(asset))
); );
// 收集成功的结果 // 收集成功的结果
for (const result of batchResults) { for (const result of batchResults) {
if (result.status === 'fulfilled' && result.value) { if (result.status === 'fulfilled' && result.value) {
results.push(result.value); results.push(result.value);
} }
} }
};
// 添加小延迟,避免过多占用系统资源 // 使用 Promise.all 并行处理所有批次
if (i + CONCURRENCY_LIMIT < assets.length) { const batches = [];
await new Promise(resolve => setTimeout(resolve, 100)); for (let i = 0; i < assets.length; i += CONCURRENCY_LIMIT) {
} batches.push(assets.slice(i, i + CONCURRENCY_LIMIT));
}
// 并行处理所有批次,但限制并发数量
for (let i = 0; i < batches.length; i += CONCURRENCY_LIMIT) {
const batchGroup = batches.slice(i, i + CONCURRENCY_LIMIT);
await Promise.all(batchGroup.map(processBatch));
} }
return results; return results;

View File

@ -60,7 +60,8 @@ export const useUploadManager = () => {
console.log('useUploadManager focused, existing session found. Monitoring progress.'); console.log('useUploadManager focused, existing session found. Monitoring progress.');
// If a session exists, just start monitoring. // If a session exists, just start monitoring.
manageUploadState(true); // Initial check manageUploadState(true); // Initial check
interval = setInterval(manageUploadState, 2000); // 将轮询间隔从2秒增加到3秒减少资源消耗
interval = setInterval(manageUploadState, 3000);
} else { } else {
// If no session, then try to trigger a new upload. // If no session, then try to trigger a new upload.
console.log('useUploadManager focused, no existing session. Triggering foreground media upload check.'); console.log('useUploadManager focused, no existing session. Triggering foreground media upload check.');
@ -73,7 +74,8 @@ export const useUploadManager = () => {
console.log(`New upload session started with time: ${newSessionStartTimeStr}, beginning to monitor...`); console.log(`New upload session started with time: ${newSessionStartTimeStr}, beginning to monitor...`);
// A new session was started, so start monitoring. // A new session was started, so start monitoring.
manageUploadState(); // Initial check manageUploadState(); // Initial check
interval = setInterval(manageUploadState, 2000); // 将轮询间隔从2秒增加到3秒减少资源消耗
interval = setInterval(manageUploadState, 3000);
} }
} }
}; };