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 ( +
+ Loading workspace… +
+ ); +} 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 && ( - + + + )} );