React & Frontend

How I Build a 95+ PageSpeed React Site (My Exact Process)

··7 min read

Achieving a 95+ PageSpeed score on a React site requires code splitting, lazy loading images and components, non-blocking font loading, optimized SVG/WebP assets, and a granular Vite build configuration. These optimizations together can reduce initial JS payload from 800KB+ to under 150KB.

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.

Frequently Asked Questions

How do I improve my React website's PageSpeed score?

Start with code splitting in Vite, replace full framer-motion with LazyMotion, make Google Fonts non-blocking, and add lazy loading to all below-fold images and components. These four steps typically push scores from 60–70 to 90+.

What PageSpeed score should a business website aim for?

Aim for 90+ on both mobile and desktop. Scores of 95+ on mobile are achievable with proper optimization and directly correlate with better Google rankings and lower bounce rates.

Ready to get started?

Want a 95+ PageSpeed Website? Let's Talk

Contact Manish →

Related Articles