diff --git a/web/src/App.tsx b/web/src/App.tsx
index 7fde2de..f9f9460 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -1,10 +1,9 @@
-import { useState, useEffect, useCallback, useRef } from 'react';
+import { Suspense, lazy, useState, useEffect, useCallback, useRef } from 'react';
import { BrowserRouter } from 'react-router-dom';
import { useWebSocket } from './hooks/useWebSocket';
import { useAuth } from './components/AuthContext';
import { Login } from './components/Login';
import { ResetPassword } from './components/ResetPassword';
-import { ChatControl } from './components/ChatControl';
import { AppContext } from './context/AppContext';
import { AppShell } from './components/layout/AppShell';
import { useBacktestFeatureGate } from './backtest/useBacktestFeatureGate';
@@ -12,6 +11,8 @@ import { useTabFeatureFlags } from './hooks/useTabFeatureFlags';
import { tradingRuntime, tradingTelemetry } from './lib/runtime';
import { createTradeProfile, fetchTradeProfiles, updateTradeProfile } from './lib/profileApi';
+const ChatControl = lazy(() => import('./components/ChatControl').then((mod) => ({ default: mod.ChatControl })));
+
// ─── Helpers (preserved from original App.tsx) ───────────────────────────────
export const resolveProfileNameForAction = (
@@ -262,7 +263,9 @@ function App() {
)}
{/* Floating AI strategy assistant */}
-
+
+
+
);
diff --git a/web/src/components/layout/AppShell.tsx b/web/src/components/layout/AppShell.tsx
index 8313990..5fa1ccf 100644
--- a/web/src/components/layout/AppShell.tsx
+++ b/web/src/components/layout/AppShell.tsx
@@ -1,17 +1,41 @@
+import { Suspense, lazy } from 'react';
import { Link, Routes, Route, useLocation } from 'react-router-dom';
import { Sidebar } from './Sidebar';
import { Header } from './Header';
import { RightPanel } from './RightPanel';
import { Button } from '../ui/button';
-import { HomeView } from '../../views/HomeView';
-import { PortfolioView } from '../../views/PortfolioView';
-import { ResearchView } from '../../views/ResearchView';
-import { SimpleView } from '../../views/SimpleView';
-import { MarketsView } from '../../views/MarketsView';
-import { ScreenerView } from '../../views/ScreenerView';
-import { WatchlistView } from '../../views/WatchlistView';
-import { AlertsView } from '../../views/AlertsView';
-import { SettingsView } from '../../views/SettingsView';
+
+const HomeView = lazy(() => import('../../views/HomeView').then((mod) => ({ default: mod.HomeView })));
+const PortfolioView = lazy(() => import('../../views/PortfolioView').then((mod) => ({ default: mod.PortfolioView })));
+const ResearchView = lazy(() => import('../../views/ResearchView').then((mod) => ({ default: mod.ResearchView })));
+const SimpleView = lazy(() => import('../../views/SimpleView').then((mod) => ({ default: mod.SimpleView })));
+const MarketsView = lazy(() => import('../../views/MarketsView').then((mod) => ({ default: mod.MarketsView })));
+const ScreenerView = lazy(() => import('../../views/ScreenerView').then((mod) => ({ default: mod.ScreenerView })));
+const WatchlistView = lazy(() => import('../../views/WatchlistView').then((mod) => ({ default: mod.WatchlistView })));
+const AlertsView = lazy(() => import('../../views/AlertsView').then((mod) => ({ default: mod.AlertsView })));
+const SettingsView = lazy(() => import('../../views/SettingsView').then((mod) => ({ default: mod.SettingsView })));
+
+function RouteFallback() {
+ return (
+
+ );
+}
function NotFoundView() {
const location = useLocation();
@@ -64,18 +88,20 @@ export function AppShell() {
{/* Scrollable main content */}
-
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
+ }>
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
{/* Fixed right panel */}
diff --git a/web/src/views/MarketsView.tsx b/web/src/views/MarketsView.tsx
index 3f82341..b884a4b 100644
--- a/web/src/views/MarketsView.tsx
+++ b/web/src/views/MarketsView.tsx
@@ -1,10 +1,11 @@
-import { useState } from 'react';
+import { Suspense, lazy, useState } from 'react';
import { useAppContext } from '../context/AppContext';
-import { MarketplaceTab } from '../tabs/MarketplaceTab';
import { TopVolatile, AISetups } from '../components/MarketOpportunities';
import type { StrategyPreset } from '../lib/PresetRegistry';
import { PageHeader } from '../components/ui/page-header';
+const MarketplaceTab = lazy(() => import('../tabs/MarketplaceTab').then((mod) => ({ default: mod.MarketplaceTab })));
+
export function MarketsView() {
const { botState, showMarketplaceTab } = useAppContext();
const [, setClonedPreset] = useState
(null);
@@ -22,7 +23,9 @@ export function MarketsView() {
{showMarketplaceTab && (
-
+
+
+
)}
);