perf(ui): route-level code splitting (#29)
CI / backend (push) Successful in 54s
CI / frontend (push) Successful in 13s
CI / format (push) Successful in 52s
CI / db-tests (push) Successful in 56s
CI / backend (pull_request) Successful in 52s
CI / frontend (pull_request) Successful in 13s
CI / format (pull_request) Successful in 49s
CI / db-tests (pull_request) Successful in 52s
Deploy Staging / deploy (push) Successful in 26s
Security / secrets (push) Successful in 5s
Security / dependencies (push) Successful in 1m0s
Security / secrets (pull_request) Successful in 5s
Security / dependencies (pull_request) Successful in 1m2s

This commit was merged in pull request #29.
This commit is contained in:
2026-07-02 16:53:31 +02:00
parent a3d8654198
commit 7ec4f1ddb8
+34 -23
View File
@@ -1,42 +1,53 @@
import React from 'react';
import React, { Suspense, lazy } from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import Landing from './pages/Landing.jsx';
import Dashboard from './pages/Dashboard.jsx';
import Senders from './pages/Senders.jsx';
import Cleanup from './pages/Cleanup.jsx';
import Unsubscribe from './pages/Unsubscribe.jsx';
import FolderView from './pages/FolderView.jsx';
import SearchResults from './pages/SearchResults.jsx';
import Layout from './components/Layout.jsx';
import DesignSystem from './pages/DesignSystem.jsx';
import { ToastProvider, TooltipProvider } from './components/ui';
import '@fontsource-variable/inter';
import './index.css';
import './styles.css';
// Route-level code splitting: each page loads its own chunk on first visit, so the
// initial bundle no longer carries Chart.js / grid-layout / every page at once.
// Landing + Layout stay eager (they're the first paint).
const Dashboard = lazy(() => import('./pages/Dashboard.jsx'));
const Senders = lazy(() => import('./pages/Senders.jsx'));
const Cleanup = lazy(() => import('./pages/Cleanup.jsx'));
const Unsubscribe = lazy(() => import('./pages/Unsubscribe.jsx'));
const FolderView = lazy(() => import('./pages/FolderView.jsx'));
const SearchResults = lazy(() => import('./pages/SearchResults.jsx'));
const DesignSystem = lazy(() => import('./pages/DesignSystem.jsx'));
// Minimal, theme-correct route fallback (skeleton-style, per the design system).
const RouteFallback = () => (
<div className="p-6 text-sm text-muted-foreground" aria-busy="true">Loading</div>
);
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<ToastProvider>
<TooltipProvider delayDuration={200}>
<BrowserRouter>
<Routes>
{/* Public landing page */}
<Route path="/" element={<Landing />} />
<Suspense fallback={<RouteFallback />}>
<Routes>
{/* Public landing page */}
<Route path="/" element={<Landing />} />
{/* Authenticated app */}
<Route path="/app" element={<Layout />}>
<Route index element={<Dashboard />} />
<Route path="senders" element={<Senders />} />
<Route path="cleanup" element={<Cleanup />} />
<Route path="unsubscribe" element={<Unsubscribe />} />
<Route path="folder/:slug" element={<FolderView />} />
<Route path="search" element={<SearchResults />} />
<Route path="design" element={<DesignSystem />} />
</Route>
{/* Authenticated app */}
<Route path="/app" element={<Layout />}>
<Route index element={<Dashboard />} />
<Route path="senders" element={<Senders />} />
<Route path="cleanup" element={<Cleanup />} />
<Route path="unsubscribe" element={<Unsubscribe />} />
<Route path="folder/:slug" element={<FolderView />} />
<Route path="search" element={<SearchResults />} />
<Route path="design" element={<DesignSystem />} />
</Route>
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Suspense>
</BrowserRouter>
</TooltipProvider>
</ToastProvider>