refactor(core): optimize state management and component rendering performance
Some checks failed
Frontend CI / ota-ios (push) Successful in 1m39s
Frontend CI / ota-android (push) Successful in 1m39s
Frontend CI / build-android-apk (push) Failing after 1m52s
Frontend CI / build-and-push-web (push) Successful in 22m5s

Improve application stability and performance by optimizing Zustand store usage, implementing memoization patterns, and introducing persistent authentication.

- **State Management**:
  - Refactor Zustand selectors to use `useShallow` and `getState()` to prevent unnecessary re-renders and infinite loops in hooks.
  - Implement `persist` middleware for `authStore` to maintain user sessions across restarts.
  - Introduce `buildStateCached` in `themeStore` to reduce redundant theme object computations.
- **Performance & Rendering**:
  - Implement `useMemo` for stable object/array references in `ImageGallery` and list components to prevent expensive re-renders.
  - Replace inline arrow functions with `useCallback` in complex screens like `ChatScreen` and `MessageListScreen`.
  - Optimize `FlashList` usage by providing stable `key` and `extraData` props.
- **Architecture**:
  - Decouple unread count fetching by introducing `useUnreadCountQuery` (React Query) for better caching and synchronization.
  - Add `useChannels` hook to centralize channel data fetching.
  - Refine `SessionGate` logic to allow immediate rendering of authenticated users while verifying in the background.
This commit is contained in:
2026-05-18 00:39:25 +08:00
parent fb67fb6d5b
commit 4fde3e403a
18 changed files with 195 additions and 118 deletions

View File

@@ -16,6 +16,7 @@ import { useShallow } from 'zustand/react/shallow';
import { ConversationResponse, MessageResponse, MessageSegment } from '../../types/dto';
import { messageManager } from './MessageManager';
import { useMessageStore } from './store';
import { useUnreadCountQuery } from '../../hooks/useUnreadCount';
// ==================== useConversations - 获取会话列表 ====================
@@ -43,16 +44,19 @@ export function useConversations(): UseConversationsReturn {
console.error('[useConversations] 初始化失败:', error);
});
// 冷启动兜底:延迟做一次强制刷新,避免首次因时序问题拿到空列表
const coldStartSyncTimer = setTimeout(() => {
messageManager.refreshConversations(true, 'hooks-initial-refresh').catch(error => {
console.error('[useConversations] 冷启动强制刷新失败:', error);
});
}, 1200);
// 仅在首次初始化时做一次冷启动兜底刷新,避免每次挂载都触发
const store = useMessageStore.getState();
if (!store.isInitialized) {
const coldStartSyncTimer = setTimeout(() => {
messageManager.refreshConversations(true, 'hooks-initial-refresh').catch(error => {
console.error('[useConversations] 冷启动强制刷新失败:', error);
});
}, 1200);
return () => {
clearTimeout(coldStartSyncTimer);
};
return () => {
clearTimeout(coldStartSyncTimer);
};
}
}, []);
// 监听 hasMore 变化
@@ -249,15 +253,11 @@ interface UseUnreadCountReturn {
* 使用 Zustand selector 直接订阅未读数变化
*/
export function useUnreadCount(): UseUnreadCountReturn {
// 使用 Zustand selector 直接订阅未读数
// Use React Query for fetching (caching + auto-refetch), Zustand selectors for reading
useUnreadCountQuery();
const totalUnreadCount = useMessageStore(state => state.totalUnreadCount);
const systemUnreadCount = useMessageStore(state => state.systemUnreadCount);
useEffect(() => {
// 初始化时获取最新未读数
messageManager.fetchUnreadCount();
}, []);
return {
totalUnreadCount,
systemUnreadCount,
@@ -271,14 +271,11 @@ export function useUnreadCount(): UseUnreadCountReturn {
* 使用 Zustand selector 直接订阅
*/
export function useTotalUnreadCount(): number {
// Use React Query for fetching, Zustand selectors for reading
useUnreadCountQuery();
const totalUnreadCount = useMessageStore(state => state.totalUnreadCount);
const systemUnreadCount = useMessageStore(state => state.systemUnreadCount);
useEffect(() => {
// 初始化时获取最新未读数
messageManager.fetchUnreadCount();
}, []);
return totalUnreadCount + systemUnreadCount;
}