Skip to content

React Performance Optimization: 10 Techniques I Use in Production

Practical React performance patterns I've used at India Today Group to optimize rendering, reduce bundle size, and deliver sub-second load times for millions of users.

Topic
React.js
Reading time
10 min
Length
425 words
Published
Mar 1, 2026
In this article
  1. 1. Memoization Done Right
  2. 2. Code Splitting with Dynamic Imports
  3. 3. Virtual Scrolling for Large Lists
  4. 4. Image Optimization with Next.js
  5. 5. Debouncing & Throttling API Calls
  6. 6. State Management Architecture
  7. 7. Bundle Analysis & Tree Shaking
  8. 8. Lazy Loading Below-the-Fold
  9. 9. Web Workers for Heavy Computation
  10. 10. Profiling with React DevTools
  11. Results

After building React applications for 9+ years across companies like India Today Group, Clove Dental, and multiple startups, I've compiled the performance techniques that actually matter in production.

1. Memoization Done Right

Most developers misuse React.memo() and useMemo(). The key is to only memoize components that receive referentially unstable props and render expensive trees.

// ❌ Useless memoizationBuilding and maintaining personal products and freelance projects alongside full-time work
const Button = React.memo(({ onClick }) => <button onClick={onClick}>Click</button>);

// ✅ Useful — prevents expensive list re-renders
const DataTable = React.memo(({ rows, columns, onSort }) => {
  // Renders 1000+ rows with complex cells
  return <table>...</table>;
});

2. Code Splitting with Dynamic Imports

At India Today, our editorial dashboard has 40+ features. Loading everything upfront would be insane. We use route-based and component-based splitting:

// Route-based splitting in Next.js
const ElectionDashboard = dynamic(() => import('./ElectionDashboard'), {
  loading: () => <DashboardSkeleton />,
  ssr: false, // client-only for chart libraries
});

3. Virtual Scrolling for Large Lists

When rendering election results with 500+ constituencies, virtual scrolling is essential. We use react-window to render only visible rows:

import { FixedSizeList } from 'react-window';

<FixedSizeList height={600} itemCount={constituencies.length} itemSize={72}>
  {({ index, style }) => <ConstituencyRow data={constituencies[index]} style={style} />}
</FixedSizeList>

4. Image Optimization with Next.js

We reduced LCP by 40% by switching to next/image with proper sizing, priority loading for above-fold images, and blur placeholders.

5. Debouncing & Throttling API Calls

Search autocomplete in our CMS fires on every keystroke. Without debouncing, that's 10+ API calls per second:

const debouncedSearch = useMemo(
  () => debounce((query) => fetchResults(query), 300),
  []
);

6. State Management Architecture

We moved from Redux to a hybrid approach — React Context for UI state, React Query/SWR for server state. This eliminated 60% of our Redux boilerplate.

7. Bundle Analysis & Tree Shaking

Run npx next build --analyze regularly. We found that importing lodash instead of lodash/debounce added 70KB to our bundle.

8. Lazy Loading Below-the-Fold

Using Intersection Observer to load components only when they scroll into view — exactly what this portfolio uses for scroll animations.

9. Web Workers for Heavy Computation

Election night data processing (parsing 10,000+ results in real-time) runs in a Web Worker to keep the UI thread responsive.

10. Profiling with React DevTools

The React Profiler is your best friend. We profile every release candidate and flag any component that re-renders more than 3 times per user interaction.

Results

These optimizations helped us achieve: LCP under 1.2s, TTI under 2s, and 95+ Lighthouse performance score on India Today's editorial platform serving millions of daily users.

Deepak Kumar

Written by

Deepak Kumar

Sr Software Engineer at India Today Group | Aaj Tak · MERN Stack · Generative AI

I build production web applications and Generative AI systems — React and Next.js on the front, Node.js and RAG pipelines behind them. I write here about what those systems actually do once real traffic hits them.

Message me