perf(ui): route-level code splitting #29
+34
-23
@@ -1,42 +1,53 @@
|
|||||||
import React from 'react';
|
import React, { Suspense, lazy } from 'react';
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
|
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
|
||||||
import Landing from './pages/Landing.jsx';
|
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 Layout from './components/Layout.jsx';
|
||||||
import DesignSystem from './pages/DesignSystem.jsx';
|
|
||||||
import { ToastProvider, TooltipProvider } from './components/ui';
|
import { ToastProvider, TooltipProvider } from './components/ui';
|
||||||
import '@fontsource-variable/inter';
|
import '@fontsource-variable/inter';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import './styles.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(
|
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<ToastProvider>
|
<ToastProvider>
|
||||||
<TooltipProvider delayDuration={200}>
|
<TooltipProvider delayDuration={200}>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Suspense fallback={<RouteFallback />}>
|
||||||
{/* Public landing page */}
|
<Routes>
|
||||||
<Route path="/" element={<Landing />} />
|
{/* Public landing page */}
|
||||||
|
<Route path="/" element={<Landing />} />
|
||||||
|
|
||||||
{/* Authenticated app */}
|
{/* Authenticated app */}
|
||||||
<Route path="/app" element={<Layout />}>
|
<Route path="/app" element={<Layout />}>
|
||||||
<Route index element={<Dashboard />} />
|
<Route index element={<Dashboard />} />
|
||||||
<Route path="senders" element={<Senders />} />
|
<Route path="senders" element={<Senders />} />
|
||||||
<Route path="cleanup" element={<Cleanup />} />
|
<Route path="cleanup" element={<Cleanup />} />
|
||||||
<Route path="unsubscribe" element={<Unsubscribe />} />
|
<Route path="unsubscribe" element={<Unsubscribe />} />
|
||||||
<Route path="folder/:slug" element={<FolderView />} />
|
<Route path="folder/:slug" element={<FolderView />} />
|
||||||
<Route path="search" element={<SearchResults />} />
|
<Route path="search" element={<SearchResults />} />
|
||||||
<Route path="design" element={<DesignSystem />} />
|
<Route path="design" element={<DesignSystem />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path="*" element={<Navigate to="/" replace />} />
|
<Route path="*" element={<Navigate to="/" replace />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
</Suspense>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</ToastProvider>
|
</ToastProvider>
|
||||||
|
|||||||
Reference in New Issue
Block a user