Skip to content

Commit bb5cc31

Browse files
Merge pull request #37 from vincentgrobler/feature/ticket-6.2-performance
perf(ticket-6.2): code-splitting and bundle optimization
2 parents dac4379 + 93881ea commit bb5cc31

2 files changed

Lines changed: 70 additions & 43 deletions

File tree

src/App.tsx

Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,70 @@
11
// SPDX-License-Identifier: AGPL-3.0-or-later
22
// Copyright (C) 2026 CrewForm
33

4+
import { lazy, Suspense } from 'react'
45
import { Routes, Route } from 'react-router-dom'
56
import { RootLayout } from '@/layouts/RootLayout'
67
import { AuthGuard } from '@/components/auth/AuthGuard'
7-
import { Dashboard } from '@/pages/Dashboard'
8-
import { Agents } from '@/pages/Agents'
9-
import { Teams } from '@/pages/Teams'
10-
import { Tasks } from '@/pages/Tasks'
11-
import { Marketplace } from '@/pages/Marketplace'
12-
import { Settings } from '@/pages/Settings'
13-
import { Auth } from '@/pages/Auth'
14-
import { AuthCallback } from '@/pages/AuthCallback'
15-
import { CreateAgent } from '@/pages/CreateAgent'
16-
import { AgentDetail } from '@/pages/AgentDetail'
17-
import { TaskDetail } from '@/pages/TaskDetail'
18-
import { TeamDetail } from '@/pages/TeamDetail'
19-
import { TeamRunDetail } from '@/pages/TeamRunDetail'
20-
import { Analytics } from '@/pages/Analytics'
8+
import { Loader2 } from 'lucide-react'
9+
10+
// ── Lazy-loaded pages ────────────────────────────────────────────────────────
11+
const Dashboard = lazy(() => import('@/pages/Dashboard').then(m => ({ default: m.Dashboard })))
12+
const Agents = lazy(() => import('@/pages/Agents').then(m => ({ default: m.Agents })))
13+
const Teams = lazy(() => import('@/pages/Teams').then(m => ({ default: m.Teams })))
14+
const Tasks = lazy(() => import('@/pages/Tasks').then(m => ({ default: m.Tasks })))
15+
const Marketplace = lazy(() => import('@/pages/Marketplace').then(m => ({ default: m.Marketplace })))
16+
const Settings = lazy(() => import('@/pages/Settings').then(m => ({ default: m.Settings })))
17+
const Auth = lazy(() => import('@/pages/Auth').then(m => ({ default: m.Auth })))
18+
const AuthCallback = lazy(() => import('@/pages/AuthCallback').then(m => ({ default: m.AuthCallback })))
19+
const CreateAgent = lazy(() => import('@/pages/CreateAgent').then(m => ({ default: m.CreateAgent })))
20+
const AgentDetail = lazy(() => import('@/pages/AgentDetail').then(m => ({ default: m.AgentDetail })))
21+
const TaskDetail = lazy(() => import('@/pages/TaskDetail').then(m => ({ default: m.TaskDetail })))
22+
const TeamDetail = lazy(() => import('@/pages/TeamDetail').then(m => ({ default: m.TeamDetail })))
23+
const TeamRunDetail = lazy(() => import('@/pages/TeamRunDetail').then(m => ({ default: m.TeamRunDetail })))
24+
const Analytics = lazy(() => import('@/pages/Analytics').then(m => ({ default: m.Analytics })))
25+
26+
// ── Suspense fallback ────────────────────────────────────────────────────────
27+
function PageLoader() {
28+
return (
29+
<div className="flex h-full items-center justify-center">
30+
<Loader2 className="h-8 w-8 animate-spin text-brand-primary" />
31+
</div>
32+
)
33+
}
2134

2235
export function App() {
2336
return (
24-
<Routes>
25-
{/* Auth routes — public */}
26-
<Route path="/auth" element={<Auth />} />
27-
<Route path="/auth/signup" element={<Auth />} />
28-
<Route path="/auth/forgot-password" element={<Auth />} />
29-
<Route path="/auth/reset-password" element={<Auth />} />
30-
<Route path="/auth/callback" element={<AuthCallback />} />
37+
<Suspense fallback={<PageLoader />}>
38+
<Routes>
39+
{/* Auth routes — public */}
40+
<Route path="/auth" element={<Auth />} />
41+
<Route path="/auth/signup" element={<Auth />} />
42+
<Route path="/auth/forgot-password" element={<Auth />} />
43+
<Route path="/auth/reset-password" element={<Auth />} />
44+
<Route path="/auth/callback" element={<AuthCallback />} />
3145

32-
{/* App routes — protected */}
33-
<Route
34-
element={
35-
<AuthGuard>
36-
<RootLayout />
37-
</AuthGuard>
38-
}
39-
>
40-
<Route path="/" element={<Dashboard />} />
41-
<Route path="/agents" element={<Agents />} />
42-
<Route path="/agents/new" element={<CreateAgent />} />
43-
<Route path="/agents/:id" element={<AgentDetail />} />
44-
<Route path="/teams" element={<Teams />} />
45-
<Route path="/teams/:id" element={<TeamDetail />} />
46-
<Route path="/teams/:teamId/runs/:runId" element={<TeamRunDetail />} />
47-
<Route path="/tasks" element={<Tasks />} />
48-
<Route path="/tasks/:id" element={<TaskDetail />} />
49-
<Route path="/marketplace" element={<Marketplace />} />
50-
<Route path="/analytics" element={<Analytics />} />
51-
<Route path="/settings" element={<Settings />} />
52-
</Route>
53-
</Routes>
46+
{/* App routes — protected */}
47+
<Route
48+
element={
49+
<AuthGuard>
50+
<RootLayout />
51+
</AuthGuard>
52+
}
53+
>
54+
<Route path="/" element={<Dashboard />} />
55+
<Route path="/agents" element={<Agents />} />
56+
<Route path="/agents/new" element={<CreateAgent />} />
57+
<Route path="/agents/:id" element={<AgentDetail />} />
58+
<Route path="/teams" element={<Teams />} />
59+
<Route path="/teams/:id" element={<TeamDetail />} />
60+
<Route path="/teams/:teamId/runs/:runId" element={<TeamRunDetail />} />
61+
<Route path="/tasks" element={<Tasks />} />
62+
<Route path="/tasks/:id" element={<TaskDetail />} />
63+
<Route path="/marketplace" element={<Marketplace />} />
64+
<Route path="/analytics" element={<Analytics />} />
65+
<Route path="/settings" element={<Settings />} />
66+
</Route>
67+
</Routes>
68+
</Suspense>
5469
)
5570
}

vite.config.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,17 @@ export default defineConfig({
2020
build: {
2121
sourcemap: true,
2222
target: 'es2022',
23+
rollupOptions: {
24+
output: {
25+
manualChunks: {
26+
// Heavy charting library — only loaded on Analytics/Dashboard
27+
recharts: ['recharts'],
28+
// React core — stable, cached long-term
29+
'react-vendor': ['react', 'react-dom', 'react-router-dom'],
30+
// Supabase client
31+
supabase: ['@supabase/supabase-js'],
32+
},
33+
},
34+
},
2335
},
2436
})

0 commit comments

Comments
 (0)