Skip to content

Commit 931e06d

Browse files
committed
Performance: Stop unnecessary Sidebar re-renders during chat responses
I noticed the Sidebar was re-rendering on every single text chunk from the LLM. This was making the UI feel a bit sluggish and was spamming the console, which made debugging a pain. A cascade of unnecessary re-renders occurred because parent components were creating 'new' functions for props like onClose and clearChat on every render. Here's how I approached the issue: 1. Added React.memo to Sidebar.tsx, enabling it to ignore prop changes that aren't actually different. 2. Stabilized the parents Layout.tsx and Chat\Header.tsx by wrapping the functions being passed down ('onClose', etc.) in 'useCallback'; stopping them from being treated as 'new' on every render. 3. Updated the custom hooks, useMessage and useMessageOption, wrapping all of their returned functions in useCallback or useMemo; ensuring they too provide stable/consistent functions to any components that use them. After these changes the Sidebar should only update when it actually needs to, making the app feel a bit faster and the console much cleaner.
1 parent dbcece6 commit 931e06d

File tree

5 files changed

+2036
-1864
lines changed

5 files changed

+2036
-1864
lines changed

src/components/Layouts/Layout.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from "react"
1+
import React, { useState, useCallback } from "react"
22

33
import { Sidebar } from "../Option/Sidebar"
44
import { Drawer, Tooltip } from "antd"
@@ -34,11 +34,18 @@ export default function OptionLayout({
3434
temporaryChat,
3535
setSelectedSystemPrompt,
3636
setContextFiles,
37-
useOCR
37+
useOCR,
38+
history // <-- Destructure history here as it's used in the Sidebar props
3839
} = useMessageOption()
3940
const queryClient = useQueryClient()
4041
const { setSystemPrompt } = useStoreChatModelSettings()
4142

43+
// Create a stable function for onClose using useCallback.
44+
// This prevents a new function from being created on every render.
45+
const handleCloseSidebar = useCallback(() => {
46+
setSidebarOpen(false)
47+
}, [])
48+
4249
return (
4350
<div className="flex h-full w-full">
4451
<main className="relative h-dvh w-full">
@@ -93,11 +100,11 @@ export default function OptionLayout({
93100
}
94101
placement="left"
95102
closeIcon={null}
96-
onClose={() => setSidebarOpen(false)}
103+
onClose={handleCloseSidebar}
97104
open={sidebarOpen}>
98105
<Sidebar
99106
isOpen={sidebarOpen}
100-
onClose={() => setSidebarOpen(false)}
107+
onClose={handleCloseSidebar}
101108
setMessages={setMessages}
102109
setHistory={setHistory}
103110
setHistoryId={setHistoryId}

0 commit comments

Comments
 (0)