feat(perf): implement route lazy loading for About and Contact pages

- Splits About and Contact pages into separate chunks using React.lazy and Suspense.
- Keeps Home page eager loaded to prevent layout shifts.
- Adds PageLoader component as a fallback for Suspense.
- Reduces initial bundle size by loading secondary pages only when needed.
This commit is contained in:
google-labs-jules[bot]
2026-01-26 01:41:35 +00:00
parent 13df58342a
commit 0fe47a3790
5 changed files with 52 additions and 6 deletions

View File

@@ -1,3 +1,7 @@
## 2024-05-22 - Missing Scripts and Environment ## 2024-05-22 - Missing Scripts and Environment
**Learning:** The project lacks `lint` script in `package.json`. Running `pnpm lint` might invoke system tools (like Android Lint?) instead of failing or doing nothing useful. Always check `package.json` scripts first. **Learning:** The project lacks `lint` script in `package.json`. Running `pnpm lint` might invoke system tools (like Android Lint?) instead of failing or doing nothing useful. Always check `package.json` scripts first.
**Action:** Use specific commands like `pnpm exec tsc --noEmit` or `npx vitest` as discovered/documented, rather than assuming standard scripts exist. **Action:** Use specific commands like `pnpm exec tsc --noEmit` or `npx vitest` as discovered/documented, rather than assuming standard scripts exist.
## 2025-01-26 - Missing Node Modules
**Learning:** The environment might lack `node_modules` completely, preventing `npx vitest` or `pnpm exec tsc` from running even if dependencies are listed in `package.json`. Network restrictions may prevent `pnpm install`.
**Action:** When `node_modules` is missing and cannot be installed, rely on static analysis, careful code review, and verifying file contents manually. Do not assume tests can run.

View File

@@ -1,9 +1,16 @@
import { Suspense, lazy } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom'; import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { LanguageProvider } from './i18n'; import { LanguageProvider } from './i18n';
import { Navbar, Footer, FancyCursor, ScrollToTop } from './components/layout'; import { Navbar, Footer, FancyCursor, ScrollToTop } from './components/layout';
import { Home, About, Contact } from './pages'; import { Home } from './pages/Home';
import { PageLoader } from './components/ui';
import './styles/global.css'; import './styles/global.css';
// Lazy load pages to reduce initial bundle size.
// Home is imported directly to prevent layout shift on initial load.
const About = lazy(() => import('./pages/About').then(module => ({ default: module.About })));
const Contact = lazy(() => import('./pages/Contact').then(module => ({ default: module.Contact })));
export function App() { export function App() {
return ( return (
<LanguageProvider> <LanguageProvider>
@@ -11,11 +18,14 @@ export function App() {
<ScrollToTop /> <ScrollToTop />
<FancyCursor /> <FancyCursor />
<Navbar /> <Navbar />
<Routes> {/* Suspense handles the loading state for lazy-loaded routes */}
<Route path="/" element={<Home />} /> <Suspense fallback={<PageLoader />}>
<Route path="/about" element={<About />} /> <Routes>
<Route path="/contact" element={<Contact />} /> <Route path="/" element={<Home />} />
</Routes> <Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</Suspense>
<Footer /> <Footer />
</BrowserRouter> </BrowserRouter>
</LanguageProvider> </LanguageProvider>

View File

@@ -0,0 +1,22 @@
.container {
display: flex;
align-items: center;
justify-content: center;
min-height: 60vh;
width: 100%;
}
.loader {
width: 40px;
height: 40px;
border: 3px solid var(--md-sys-color-surface-container-highest);
border-top-color: var(--md-sys-color-primary);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}

View File

@@ -0,0 +1,9 @@
import styles from './PageLoader.module.css';
export function PageLoader() {
return (
<div className={styles.container}>
<div className={styles.loader} />
</div>
);
}

View File

@@ -1,3 +1,4 @@
export { Button } from './Button'; export { Button } from './Button';
export { Card } from './Card'; export { Card } from './Card';
export { Input, Textarea } from './Input'; export { Input, Textarea } from './Input';
export { PageLoader } from './PageLoader';