Skip to content

Commit 846a33b

Browse files
perf: enhance lazy loading with fallback UI and optimize chunking
- Added LazyFallback component for better user experience during lazy loading - Updated router configuration to include HydrateFallback for lazy-loaded pages - Improved manual chunking strategy in Vite config for better performance
1 parent 3ce7d23 commit 846a33b

2 files changed

Lines changed: 16 additions & 8 deletions

File tree

app/src/router.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,37 @@
11
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
22
import { HelmetProvider } from 'react-helmet-async';
3+
import Box from '@mui/material/Box';
4+
import CircularProgress from '@mui/material/CircularProgress';
35
import { Layout, AppDataProvider } from './components/Layout';
46
import { ErrorBoundary } from './components/ErrorBoundary';
57
import { HomePage } from './pages/HomePage';
68
import { SpecPage } from './pages/SpecPage';
79
import { NotFoundPage } from './pages/NotFoundPage';
810

11+
const LazyFallback = () => (
12+
<Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '50vh' }}>
13+
<CircularProgress size={32} />
14+
</Box>
15+
);
16+
917
const router = createBrowserRouter([
1018
{
1119
path: '/',
1220
element: <Layout />,
1321
children: [
1422
{ index: true, element: <HomePage /> },
15-
{ path: 'catalog', lazy: () => import('./pages/CatalogPage').then(m => ({ Component: m.CatalogPage })) },
16-
{ path: 'legal', lazy: () => import('./pages/LegalPage').then(m => ({ Component: m.LegalPage })) },
17-
{ path: 'mcp', lazy: () => import('./pages/McpPage').then(m => ({ Component: m.McpPage })) },
23+
{ path: 'catalog', lazy: () => import('./pages/CatalogPage').then(m => ({ Component: m.CatalogPage, HydrateFallback: LazyFallback })) },
24+
{ path: 'legal', lazy: () => import('./pages/LegalPage').then(m => ({ Component: m.LegalPage, HydrateFallback: LazyFallback })) },
25+
{ path: 'mcp', lazy: () => import('./pages/McpPage').then(m => ({ Component: m.McpPage, HydrateFallback: LazyFallback })) },
1826
{ path: ':specId', element: <SpecPage /> },
1927
{ path: ':specId/:library', element: <SpecPage /> },
2028
{ path: '*', element: <NotFoundPage /> },
2129
],
2230
},
2331
// Fullscreen interactive view (outside Layout but inside AppDataProvider)
24-
{ path: 'interactive/:specId/:library', lazy: () => import('./pages/InteractivePage').then(m => ({ Component: m.InteractivePage })) },
32+
{ path: 'interactive/:specId/:library', lazy: () => import('./pages/InteractivePage').then(m => ({ Component: m.InteractivePage, HydrateFallback: LazyFallback })) },
2533
// Hidden debug dashboard (outside Layout - no header/footer)
26-
{ path: 'debug', lazy: () => import('./pages/DebugPage').then(m => ({ Component: m.DebugPage })) },
34+
{ path: 'debug', lazy: () => import('./pages/DebugPage').then(m => ({ Component: m.DebugPage, HydrateFallback: LazyFallback })) },
2735
{ path: '*', element: <NotFoundPage /> },
2836
]);
2937

app/vite.config.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ export default defineConfig({
1414
build: {
1515
rollupOptions: {
1616
output: {
17-
manualChunks: {
18-
vendor: ['react', 'react-dom', 'react-router-dom'],
19-
mui: ['@mui/material', '@mui/icons-material'],
17+
manualChunks(id) {
18+
if (id.includes('node_modules/@mui/')) return 'mui';
19+
if (id.includes('node_modules/react/') || id.includes('node_modules/react-dom/') || id.includes('node_modules/react-router-dom/')) return 'vendor';
2020
},
2121
},
2222
},

0 commit comments

Comments
 (0)