perf: fix streaming lag, memory leaks, stuck spinners, and proxy timeout (#483)
* perf: fix streaming lag, memory leaks, and proxy timeout - PERF-001: Batch all streaming parts via requestAnimationFrame instead of per-token Zustand set() calls (~100/sec → 1 per frame) - PERF-002: Fix direct state.sessionMemoryState mutation inside set() callback - PERF-003: Debounce messageStore→sessionStore subscription via rAF + 500ms title computation delay - PERF-004: Stabilize SSE callbacks with refs to prevent reconnection storms; add 5-min stuck session idle timeout - PERF-005: Bound messageCache (500 max, LRU eviction), cap registry Maps, cleanup on session eviction - PERF-006: Replace toast duration: Infinity with 30s + id-based dedup - Fix proxy timeout: POST /session/:id/message 45s → 4min (matches CLI) - Add vitest + jsdom test infrastructure (61 tests across 7 files) Addresses: #476 (stuck spinner), #358 (34GB memory leak), #190 (browser lag) * perf: virtualize tool output rendering (read, edit, write) - PERF-007: Replace per-line <SyntaxHighlighter> with VirtualizedCodeBlock: - ONE Prism.highlight() call for entire file instead of N per-line calls - @tanstack/react-virtual renders only visible rows (~30 vs 2000+) - Applied to: ToolPart (read, DiffPreview, WriteInputPreview) and ToolOutputDialog (unified diff, read content) - PERF-008: Memoize parseReadToolOutput/parseDiffToUnified via useMemo to prevent re-parsing on every re-render A 2000-line file read now mounts ~30 DOM nodes instead of 2000 SyntaxHighlighter instances, eliminating the main-thread blocking that caused UI freezes during file operations. * fix: resolve lint errors (unused vars in tests and VirtualizedCodeBlock) * chore: trim PR scope to core perf fixes * fix: restore tool-card highlight stability --------- Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Bohdan Triapitsyn
parent
989593ed72
commit
3cd6d051cb
@@ -151,6 +151,7 @@
|
||||
"@remixicon/react": "^4.7.0",
|
||||
"@streamdown/code": "^1.0.2",
|
||||
"@streamdown/mermaid": "^1.0.2",
|
||||
"@tanstack/react-virtual": "^3.13.18",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
@@ -163,6 +164,7 @@
|
||||
"http-proxy-middleware": "^3.0.5",
|
||||
"motion": "^12.23.24",
|
||||
"next-themes": "^0.4.6",
|
||||
"prismjs": "^1.30.0",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-syntax-highlighter": "^15.6.6",
|
||||
@@ -180,6 +182,7 @@
|
||||
"@tailwindcss/postcss": "^4.0.0",
|
||||
"@tauri-apps/api": "^2.9.0",
|
||||
"@types/node": "^24.3.1",
|
||||
"@types/prismjs": "^1.26.6",
|
||||
"@types/react": "^19.1.10",
|
||||
"@types/react-dom": "^19.1.7",
|
||||
"@vitejs/plugin-react": "^5.0.0",
|
||||
@@ -1105,6 +1108,10 @@
|
||||
|
||||
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.18", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.18", "@tailwindcss/oxide": "4.1.18", "postcss": "^8.4.41", "tailwindcss": "4.1.18" } }, "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g=="],
|
||||
|
||||
"@tanstack/react-virtual": ["@tanstack/react-virtual@3.13.18", "", { "dependencies": { "@tanstack/virtual-core": "3.13.18" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-dZkhyfahpvlaV0rIKnvQiVoWPyURppl6w4m9IwMDpuIjcJ1sD9YGWrt0wISvgU7ewACXx2Ct46WPgI6qAD4v6A=="],
|
||||
|
||||
"@tanstack/virtual-core": ["@tanstack/virtual-core@3.13.18", "", {}, "sha512-Mx86Hqu1k39icq2Zusq+Ey2J6dDWTjDvEv43PJtRCoEYTLyfaPnxIQ6iy7YAOK0NV/qOEmZQ/uCufrppZxTgcg=="],
|
||||
|
||||
"@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="],
|
||||
|
||||
"@tauri-apps/cli": ["@tauri-apps/cli@2.10.0", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.10.0", "@tauri-apps/cli-darwin-x64": "2.10.0", "@tauri-apps/cli-linux-arm-gnueabihf": "2.10.0", "@tauri-apps/cli-linux-arm64-gnu": "2.10.0", "@tauri-apps/cli-linux-arm64-musl": "2.10.0", "@tauri-apps/cli-linux-riscv64-gnu": "2.10.0", "@tauri-apps/cli-linux-x64-gnu": "2.10.0", "@tauri-apps/cli-linux-x64-musl": "2.10.0", "@tauri-apps/cli-win32-arm64-msvc": "2.10.0", "@tauri-apps/cli-win32-ia32-msvc": "2.10.0", "@tauri-apps/cli-win32-x64-msvc": "2.10.0" }, "bin": { "tauri": "tauri.js" } }, "sha512-ZwT0T+7bw4+DPCSWzmviwq5XbXlM0cNoleDKOYPFYqcZqeKY31KlpoMW/MOON/tOFBPgi31a2v3w9gliqwL2+Q=="],
|
||||
@@ -1251,6 +1258,8 @@
|
||||
|
||||
"@types/plist": ["@types/plist@3.0.5", "", { "dependencies": { "@types/node": "*", "xmlbuilder": ">=11.0.1" } }, "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA=="],
|
||||
|
||||
"@types/prismjs": ["@types/prismjs@1.26.6", "", {}, "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw=="],
|
||||
|
||||
"@types/react": ["@types/react@19.2.13", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-KkiJeU6VbYbUOp5ITMIc7kBfqlYkKA5KhEHVrGMmUUMt7NeaZg65ojdPk+FtNrBAOXNVM5QM72jnADjM+XVRAQ=="],
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
||||
|
||||
Reference in New Issue
Block a user