Why PageSpeed Matters (Beyond the Score)
Google uses Core Web Vitals — which PageSpeed measures — as a ranking factor. More importantly, every 100ms delay in page load reduces conversions by ~1%. For a local business website in Vasai or Mumbai, a slow site directly costs you customers.
A 95+ score also builds trust. When your prospects see a fast, smooth site, they associate it with professionalism — even if they don't consciously notice the speed.
Step 1: Granular Code Splitting in Vite
The default Vite build dumps every npm package into one massive vendor chunk. This forces the browser to download all dependencies before showing anything.
Instead, I configure `manualChunks` in `vite.config.js` to give each heavy library its own chunk:
```js manualChunks(id) { if (id.includes('framer-motion')) return 'framer-motion'; if (id.includes('react-icons')) return 'react-icons'; if (id.includes('react-router')) return 'react-router'; if (id.includes('node_modules')) return 'vendor'; } ```
This lets the browser load only what it needs immediately and defer the rest.
Step 2: LazyMotion for Framer Motion
Framer Motion's full bundle is ~300KB. Instead of importing `motion`, I use `LazyMotion` + `domAnimation` + `m`:
```jsx import { LazyMotion, domAnimation, m } from 'framer-motion'; // Wraps the component in <LazyMotion features={domAnimation}> // and replaces <motion.div> with <m.div> ```
This drops the initial Framer Motion cost from ~300KB to ~18KB — a 93% reduction.
Step 3: Non-Blocking Font Loading
Google Fonts loaded with a standard `<link rel="stylesheet">` blocks rendering. The browser waits for the font file before painting the page.
The fix: `media="print"` + `onload`:
```html <link href="https://fonts.googleapis.com/css2?family=Sora&display=swap" rel="stylesheet" media="print" onload="this.media='all'" > ```
The browser loads the font in the background and swaps it in when ready — zero render blocking.
Step 4: Lazy Load Everything Below the Fold
Any image or component not visible on initial load should be lazy loaded:
- Images: `loading="lazy"` attribute - Components: `React.lazy()` + `<Suspense>` - The hero image (LCP): preload with `<link rel="preload" fetchpriority="high">`
This ensures the browser spends its first milliseconds only on what the user actually sees.