'优化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={() => (
<View style={styles.separator} />
)}
getItemLayout={(data, index) => (
{ length: 80, offset: 80 * index, index }
)}
renderItem={({ item }) => (
<TouchableOpacity
style={styles.memoItem}

View File

@ -56,12 +56,13 @@ export default function OwnerPage() {
})
}
// 设计轮询获取数量统计
// useEffect(() => {
// const interval = setInterval(() => {
// getCountData();
// }, 1000);
// return () => clearInterval(interval);
// }, []);
useEffect(() => {
// 将轮询间隔增加到5秒减少服务器压力和电池消耗
const interval = setInterval(() => {
getCountData();
}, 5000);
return () => clearInterval(interval);
}, []);
// 初始化获取用户信息
useEffect(() => {
@ -107,6 +108,10 @@ export default function OwnerPage() {
<Ranking data={userInfoDetails.title_rankings} />
</View>
}
// 优化性能:添加 getItemLayout
getItemLayout={(data, index) => (
{ length: 1000, offset: 1000 * index, index }
)}
/>
{/* 设置弹窗 - 使用条件渲染避免层级冲突 */}
{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,
}}
resizeMode="cover"
loadingIndicatorSource={require('@/assets/images/png/placeholder.png')}
/>
</Pressable>
))}
@ -218,6 +219,7 @@ const MessageItem = ({ t, insets, item, sessionId, setModalVisible, modalVisible
style={detailsStyles.image}
onError={(error) => console.log('Image load error:', error.nativeEvent.error)}
onLoad={() => console.log('Image loaded successfully')}
loadingIndicatorSource={require('@/assets/images/png/placeholder.png')}
/>
<TouchableOpacity
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(() => {
if (userMessages.length > 0) {
setTimeout(() => {
// 延迟滚动以确保渲染完成
const timer = setTimeout(() => {
flatListRef.current?.scrollToEnd({ animated: true });
}, 100);
}, 150);
return () => clearTimeout(timer);
}
}, [userMessages]);
// 优化 FlatList 性能 - 提供 getItemLayout 方法
const getItemLayout = useCallback((data: Message[] | null | undefined, index: number) => {
// 假设每个消息项的高度大约为 100可根据实际情况调整
const averageItemHeight = 100;
return {
length: averageItemHeight,
offset: averageItemHeight * index,
index,
};
}, []);
return (
<SafeAreaView className='flex-1'>
<FlatList
@ -52,6 +65,7 @@ function ChatComponent({ userMessages, sessionId, setSelectedImages, selectedIma
updateCellsBatchingPeriod={50}
initialNumToRender={10}
windowSize={11}
getItemLayout={getItemLayout}
renderItem={({ item }) => MessageItem({ t, setSelectedImages, selectedImages, insets, item, sessionId, modalVisible, setModalVisible, setModalDetailsVisible, modalDetailsVisible })}
/>
</SafeAreaView>

View File

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

View File

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