refactor: optimize component rendering with memoization and improve state management
- Added memoization to ChatHistoryPanel, ChatMessageList, and TaskBoard components to prevent unnecessary re-renders. - Refactored HomePage to utilize useMemo for derived state calculations, enhancing performance. - Updated main.tsx to conditionally render React.StrictMode based on the environment. - Improved chat and channel store hooks to allow for selector functions, enhancing flexibility in state selection. - Enhanced streaming message handling in chat store to manage pending deltas more effectively. - Refactored LoginPage to include animated decorations for improved user experience. - Implemented lazy loading for routes in the router to optimize initial load time.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { memo, useEffect, useRef, useState } from 'react';
|
||||
import type { ChatHistoryBucket } from './types';
|
||||
import {
|
||||
ChevronDown,
|
||||
@@ -31,7 +31,7 @@ function cx(...classes: Array<string | false | null | undefined>): string {
|
||||
return classes.filter(Boolean).join(' ');
|
||||
}
|
||||
|
||||
export default function ChatHistoryPanel({
|
||||
function ChatHistoryPanel({
|
||||
buckets,
|
||||
selectedConversationId,
|
||||
loading,
|
||||
@@ -50,12 +50,17 @@ export default function ChatHistoryPanel({
|
||||
useEffect(() => {
|
||||
setCollapsedBuckets((current) => {
|
||||
const next: Record<string, boolean> = {};
|
||||
const currentKeys = Object.keys(current);
|
||||
let changed = currentKeys.length !== buckets.length;
|
||||
|
||||
for (const bucket of buckets) {
|
||||
next[bucket.key] = current[bucket.key] ?? false;
|
||||
if (current[bucket.key] !== next[bucket.key]) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return next;
|
||||
return changed ? next : current;
|
||||
});
|
||||
}, [buckets]);
|
||||
|
||||
@@ -299,3 +304,5 @@ export default function ChatHistoryPanel({
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(ChatHistoryPanel);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { memo, useEffect, useRef } from 'react';
|
||||
import type { ChatMessageItem } from './types';
|
||||
|
||||
type ChatMessageListProps = {
|
||||
@@ -6,7 +6,7 @@ type ChatMessageListProps = {
|
||||
loading?: boolean;
|
||||
};
|
||||
|
||||
export default function ChatMessageList({ messages, loading }: ChatMessageListProps) {
|
||||
function ChatMessageList({ messages, loading }: ChatMessageListProps) {
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -90,3 +90,5 @@ export default function ChatMessageList({ messages, loading }: ChatMessageListPr
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(ChatMessageList);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { memo } from 'react';
|
||||
import type { TaskItem } from './types';
|
||||
|
||||
type TaskBoardProps = {
|
||||
@@ -11,7 +12,7 @@ type TaskBoardProps = {
|
||||
currentTime?: string;
|
||||
};
|
||||
|
||||
export default function TaskBoard({
|
||||
function TaskBoard({
|
||||
activeTab,
|
||||
pendingItems,
|
||||
completedItems,
|
||||
@@ -112,3 +113,11 @@ export default function TaskBoard({
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(TaskBoard, (prevProps, nextProps) => (
|
||||
prevProps.activeTab === nextProps.activeTab
|
||||
&& prevProps.pendingItems === nextProps.pendingItems
|
||||
&& prevProps.completedItems === nextProps.completedItems
|
||||
&& prevProps.currentDateLabel === nextProps.currentDateLabel
|
||||
&& prevProps.currentTime === nextProps.currentTime
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user