Performance isn't a luxury—it's a user expectation. Whether you're building with React or Next.js, snappy performance can make or break your product’s success.
In this post, I’ll walk you through battle-tested tips and code examples to optimize rendering, improve loading time, and reduce bundle size—all without rewriting your whole app.
⚡ Why Performance Matters
- ⏳ Faster Load Time = Higher retention
- 📉 Better Core Web Vitals = SEO advantage
- 💸 Optimized Code = Lower hosting and compute costs
🧠 1. Use React Memoization Wisely
React re-renders components too often if props change frequently.
✅ Use React.memo
or useMemo
:
const ExpensiveComponent = React.memo(({ data }) => {
// Only re-renders if data changes
return <div>{data.title}</div>;
});
✅ For computed values:
const filteredItems = useMemo(() => items.filter(i => i.visible), [items]);
⚠️ Avoid overusing memoization—it can increase memory usage unnecessarily.
🛠️ 2. Optimize Images (Huge Win!)
Images are usually the heaviest assets in your app.
✅ In Next.js:
import Image from 'next/image';
<Image src="/banner.jpg" width={1200} height={400} alt="Banner" priority />
- Lazy-loaded by default
- Auto compresses
- Responsive sizes via
srcSet
✅ In React:
Use libraries like react-lazy-load-image-component
<LazyLoadImage src="/banner.jpg" alt="Banner" effect="blur" />
📦 3. Code Splitting and Dynamic Imports
✅ In React:
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
✅ In Next.js:
import dynamic from 'next/dynamic';
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
loading: () => <Skeleton />,
});
This helps reduce your initial JS bundle and improves TTI (Time to Interactive).
🔄 4. Remove Unused Dependencies and Polyfills
Tools like Bundlephobia help you check the impact of libraries.
- Replace Lodash with native functions or only import required methods:
import debounce from 'lodash/debounce'; // good
- Remove large polyfills for modern browsers if not needed.
🌐 5. Prefetching and Lazy Routes (Next.js)
Next.js supports intelligent prefetching:
<Link href="/about" prefetch={true}>About</Link>
You can also defer hydration using next/script
for third-party scripts.
<Script src="https://thirdparty.com/widget.js" strategy="lazyOnload" />
📉 6. Analyze and Trim Your Bundle
Use:
npm run analyze
Then in next.config.js
:
const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: true });
module.exports = withBundleAnalyzer({});
Look for:
- Large libraries
- Duplicates
- Unused components
🧹 7. Clean Your CSS
Too much CSS = longer paint times.
- Use CSS modules or Tailwind for scoped styles
- Remove unused styles with tools like PurgeCSS
In Tailwind:
// tailwind.config.js
content: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}']
🚀 8. Enable HTTP Caching and GZIP
This is backend-side, but vital!
- Use
Cache-Control
headers - GZIP or Brotli compress your assets
On Next.js Vercel-hosted apps, most of this is automatic!
🧪 9. Monitor Real User Performance
Use:
- Lighthouse (manual)
- Web Vitals
- LogRocket
-
Sentry +
@sentry/react
npm install web-vitals
import { getCLS, getFID, getLCP } from 'web-vitals';
getCLS(console.log);
getFID(console.log);
getLCP(console.log);
🧩 Bonus: Enable Incremental Static Regeneration (Next.js)
If using Next.js, use getStaticProps
+ revalidate
:
export async function getStaticProps() {
const data = await fetchData();
return {
props: { data },
revalidate: 60, // regenerate page every 60 seconds
};
}
✅ Final Thoughts
Performance is a mindset—not a one-time fix.
Start small, measure impact, and gradually refactor.
Got more tricks? Drop them in the comments 👇
Let’s make the web faster—together.
Top comments (0)