Optimizing React Performance: From 3s to 300ms

SC
Sarah Chen
·9 min read
Optimizing React Performance: From 3s to 300ms

The Problem

Our dashboard was taking 3 seconds to become interactive. Users were bouncing. We needed to fix it fast.

Here's the systematic approach we took to cut load time by 90%.

Step 1: Measure First

Before optimizing anything, we profiled with React DevTools and Lighthouse:

bash
npx lighthouse https://app.example.com --view

The results showed three main bottlenecks: 1. A 2MB JavaScript bundle 2. 500+ component re-renders on initial load 3. A 200-row table rendering all rows at once

Step 2: Code Splitting

We lazy-loaded every route and heavy component:

tsx
const AdminDashboard = lazy(() => import("./admin/dashboard"))
const AnalyticsChart = lazy(() => import("./charts/analytics"))

Tip

Don't just code-split routes — split heavy components within routes too. A chart library doesn't need to load until the user scrolls to it.

Step 3: Virtualization

For our 200-row table, we switched to virtual rendering:

tsx

function VirtualTable({ items }: { items: Item[] }) { const virtualizer = useVirtualizer({ count: items.length, getScrollElement: () => parentRef.current, estimateSize: () => 48, }) // Only renders visible rows } ```

Step 4: Strategic Memoization

Not everything should be memoized. We focused on: - Components that receive object/array props - Components in frequently-updating contexts - Expensive computed values

Results

MetricBeforeAfter
TTI3.2s0.3s
Bundle size2.1MB420KB
Re-renders500+45
Lighthouse3496
SC
Sarah Chen

admin

Senior frontend engineer and tech writer. Passionate about React, TypeScript, and building great developer experiences. Previously at Vercel and Stripe.

Comments (1)

TH
Tom Harrison

Those before/after metrics are impressive! Did you also try React Server Components for the initial load optimization?

Related Posts

The Complete Guide to Next.js 16 App Router
technology12 min

The Complete Guide to Next.js 16 App Router

Everything you need to know about Next.js 16's App Router — from layouts and loading states to parallel routes and intercepting routes.

SC
Sarah Chen·
7,650