perf: Major performance overhaul with virtual scrolling and context splitting

Phase 1 - Virtual Scrolling:
- Add @tanstack/react-virtual for efficient message list rendering
- Only render visible messages instead of entire history
- Fix auto-scroll using native scrollTop instead of unreliable virtualizer

Phase 2 - Context Optimization:
- Split monolithic SessionContext into 4 specialized contexts
- MessagesContext, SessionsContext, SettingsContext, UIContext
- Prevents unnecessary re-renders across unrelated components

Phase 3 - Compression & Cleanup:
- Enable Brotli compression (~23% smaller than gzip)
- Switch to fholzer/nginx-brotli:v1.28.0 image
- Add automatic upload cleanup for idle sessions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-20 17:28:03 +01:00
parent fbc8103034
commit e5d17bfad3
17 changed files with 827 additions and 564 deletions

View File

@@ -1,7 +1,10 @@
import { useState, useCallback, useEffect } from 'react';
import { AuthProvider, useAuth } from './contexts/AuthContext';
import { SessionProvider, useSessionManager } from './contexts/SessionContext';
import { HostProvider } from './contexts/HostContext';
import { SettingsProvider } from './contexts/SettingsContext';
import { UIProvider, useUI } from './contexts/UIContext';
import { MessagesProvider } from './contexts/MessagesContext';
import { SessionsProvider, useSessions } from './contexts/SessionsContext';
import { Sidebar } from './components/Sidebar';
import { TabBar } from './components/TabBar';
import { ChatPanel } from './components/ChatPanel';
@@ -10,13 +13,8 @@ import { LoginPage } from './components/LoginPage';
import { Menu, Loader2 } from 'lucide-react';
function AppContent() {
const {
sessions,
tabOrder,
splitSessions,
focusedSessionId,
createSession,
} = useSessionManager();
const { sessions, createSession } = useSessions();
const { tabOrder, splitSessions, focusedSessionId } = useUI();
const [sidebarOpen, setSidebarOpen] = useState(true);
@@ -130,9 +128,15 @@ function AuthenticatedApp() {
return (
<HostProvider>
<SessionProvider>
<AppContent />
</SessionProvider>
<SettingsProvider>
<UIProvider>
<MessagesProvider>
<SessionsProvider>
<AppContent />
</SessionsProvider>
</MessagesProvider>
</UIProvider>
</SettingsProvider>
</HostProvider>
);
}