DEV Community

Cover image for How I Made My Next.js App Blazing Fast – 10x Performance Boost!
Vikas Kushwah
Vikas Kushwah

Posted on

How I Made My Next.js App Blazing Fast – 10x Performance Boost!

⚑ No useEffect Abuse | 🌐 Server-Side Data Fetching | πŸ–ΌοΈ Optimized Images & Fonts | πŸ“¦ Less JavaScript, More Static Pages | πŸ—ƒοΈ Proper Caching & Compression

If your Next.js app feels sluggish, you're not alone. Many developers unknowingly slow down their apps with bad practicesβ€”especially client-side over-fetching, bloated JavaScript, and poor caching.

When it comes to web performance, every millisecond counts. A slow-loading Next.js app can lead to higher bounce rates, lower SEO rankings, and poor user experience.

Here’s the precise playbook I used to speed up my Next.js appβ€”and how you can do the same.

1️⃣ Server-Side Data Fetching: Stop Overusing useEffect

Many developers are to utilise useEffect to request data on the client side, which slows rendering and requires more JavaScript to be executed by the browser. To speed up data loading and cut down on pointless client-side processing, we instead employed server-side rendering (SSR) and static site generation (SSG).

❌ What to Avoid

🚫 Avoid fetching data inside useEffect unless absolutely necessary.

🚫 Don’t use client-side fetching for static data that rarely changes.

🚫 Perform heavy computations on the client that could be done at build time.

🚫 Client-side data fetching for SEO-critical content (hurts rankings)

Bad Example (Client-side Fetching in useEffect)

// ❌ Avoid this pattern

'use client'
export default function Home( ) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('/api/data')
      .then(res => res.json())
      .then(setData);
  }, []);

  if (!data) return <Loading />;

  return ( 
     <main>
          <h1>❌ Avoid this pattern</h1>
         <div>{data.content}</div>
    </main>
 );
}
Enter fullscreen mode Exit fullscreen mode

βœ… What You SHOULD Do (Best Practices)

🌐 Server-Side Data Fetching (Stop Using useEffect for Everything!)

βœ” Use getServerSideProps only when necessary (for frequently changing data).

βœ” Prefer getStaticProps with revalidation (ISR) for pages that don’t need real-time updates.

βœ” Use API routes efficiently to avoid blocking the main thread.

Good Example (Server-side Fetching )

export async function getProductsProps( ) {
  const res = await fetch('https://api.example.com/posts');
  return { 
    res.json();
    revalidate: 60, // Regenerate every 60 seconds
  };
}

export default async function Produts( ) {
  const  produtData = await  getProductsProps( );

  return ( 
     <main>
          <h1>Server-Side Data Fetching</h1>
         <div>{ produtData.content}</div>
    </main>
 );
}
Enter fullscreen mode Exit fullscreen mode

2️⃣ Optimizing Images & Fonts for Faster Rendering

Fonts and images constitute a large portion of the page weight. To lower load times and raise performance ratings, we optimised them.

❌ What to Avoid

🚫 Using <img> tag directly (misses optimization)

🚫 Avoid using large uncompressed images.

🚫 Don’t use too many custom fontsβ€”stick to one or two optimized fonts.

🚫 Never use external fonts without properly loading them asynchronously.

Bad Example ( img )

export default async function Home( ) {

  return ( 
     <main>
        <img
              src='./home.png'
              alt={productName}
               width={96}
               height={96}
            />
    </main>
 );
}
Enter fullscreen mode Exit fullscreen mode

βœ… What to Do (Best Practices)
βœ” Use Next.js Image Component (next/image) to automatically optimize images.

βœ” Enable lazy loading to load images only when they enter the viewport.

βœ” Use WebP format instead of PNG or JPEG for smaller file sizes.

βœ” Self-host custom fonts or use Google Fonts with font-display: swap to prevent render-blockings

Good Example (next/image)

import Image from 'next/image';
import { Inter } from 'next/font/google';

const inter = Inter({ subsets: ['latin'] });

export default function Hero() {
  return (
    <>
      <Image
        src="/https/dev.to/hero.jpg"
        alt="Hero Banner"
        width={1200}
        height={630}
        priority // Critical for LCP
      />
      <h1 className={inter.className}>Lightning Fast</h1>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

3️⃣ Reduce JavaScript: Use More Static Pages

Too much JavaScript increases parsing and execution time, slowing down the page. We reduced JavaScript usage by

❌ What to Avoid

🚫 Avoid shipping unnecessary JavaScript bundles.

🚫 Don’t use client-side navigation for simple static content.

🚫 Slows down rendering, adds unnecessary JavaScript.

Bad Example (client side)

useEffect(( ) => {
  fetch("/api/data")
    .then(res => res.json())
    .then(setData);
}, []);
Enter fullscreen mode Exit fullscreen mode

βœ… What to Do
βœ” Convert dynamic pages to static pages whenever possible.

βœ” Use Incremental Static Regeneration (ISR) to update static pages without full rebuilds.

βœ” Use next/link for client-side navigation without full page reloads.

Good Example (Server-side)

export async function getServerSideProps() {
  const data = await fetch("https://api.example.com/data").then(res => res.json());
  return { props: { data } };
}
Enter fullscreen mode Exit fullscreen mode

Use Static Generation Where Possible (getStaticProps)
Don't dynamically get your data if it doesn't change frequently. Instead, use getStaticProps() to pre-generate pages at build time.🌐

Good Example (Server-side)

export async function getStaticProps() {
  const res = await fetch("https://api.example.com/posts");
  const posts = await res.json();

  return { props: { posts }, revalidate: 60 }; // Refresh every 60s
}

export default function Blog({ posts }) {
  return <div>{posts.map((p) => <p key={p.id}>{p.title}</p>)}</div>;
}
Enter fullscreen mode Exit fullscreen mode

4️⃣ Implement Proper Caching & Compression

Caching and compression drastically improve loading speed by reducing the amount of data transferred over the network.

βœ… What to Do:
βœ” Use Next.js built-in caching mechanisms.

βœ” Enable Gzip or Brotli compression in your hosting environment.

βœ” Set proper Cache-Control headers for static assets.

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
compress = true     //  Enable Gzip  compression 

  images: {             // Optimixze extarnal image
    remotePatterns: [
      {
        protocol: "https",
        hostname: "**",
      },
    ],
  },
};

export default nextConfig;
Enter fullscreen mode Exit fullscreen mode

Caching = less network requests = faster page loads

πŸš€ The Final Result πŸ“Œ
Fetch data on the server (getStaticProps/getServerSideProps).
Optimize images & fonts (Next.js handles most optimizations).
Reduce JavaScript (audit, lazy-load, use Edge).
Cache aggressively (static assets should be immutable).

Implement these today for a faster Next.js app! πŸš€

πŸ™ Thank You for Reading ⚑

Top comments (0)