Back to blogs

10 Nextjs mistakes slowing your app and how to fix them fast

November 22, 2025
6 min read
10 Nextjs mistakes slowing your app and how to fix them fast

When I started building with Next.js, I thought performance would automatically be good because well, it is Next.js. But that is not true. Your app can still feel slow if you make a few small mistakes. The good thing is these mistakes are easy to fix. So in this blog I am sharing the common ones I have seen in my own projects and while helping others. I will also share what to avoid and what to do instead, in simple language.

Let us start.


1. Writing Next.js apps like plain React apps

This is the first mistake many people make including me. You install Next.js but you still write the app like Create React App. Everything is rendered on the client. All data fetching happens inside useEffect. And nothing uses server features.

This slows down the first render. The browser loads the page. Then your code loads. Then your fetch runs. Then finally your UI appears.

Fix. If you are using the App Router, fetch data inside Server Components whenever possible. Example.

export default async function Page() {
const posts = await fetch("https://api.example.com/posts").then(res => res.json());
return <PostsList posts={posts} />;
}

This sends already rendered HTML to the browser. So the user sees something instantly.


2. Importing heavy libraries directly in the page

I have done this many times. For example. You need a chart on one page. You import the whole chart library like this.

import Chart from "chart.js";

This adds the full library into your main bundle. Even if the chart appears only on one page. Users visiting other pages still download this extra JavaScript. This slows the entire app.

Fix. Use dynamic imports.

const Chart = dynamic(() => import("../components/Chart"), {
ssr: false,
});

This loads Chart code only when the user visits that page.


3. Adding images without optimisation

Large images are one of the easiest ways to slow down a site. Many developers upload a 1200px image and show it as a small icon. Or they upload PNGs that could have been WebP.

I once had a landing page that took full 2 to 3 seconds to show anything because the hero image was 1.5 MB.

Fix. Use the next/image component. And also export images in WebP or AVIF format. They are much smaller.

import Image from "next/image";

<Image src="/hero.webp" width={900} height={600} alt="Hero" />;

Next.js will handle resizing and lazy loading for you.


4. Fetching data on the client when it could be static

I once built a pricing page. The pricing never changed. But I still fetched it with useEffect. This added unnecessary waiting time for users.

Fix. If your data is mostly static like blog posts or FAQs or marketing content, generate it at build time.

In the App Router you can do this.

export const revalidate = 3600; // regenerate once an hour

This makes it static and fast. Still allows it to update sometimes.


5. Using "use client" too much

Some developers mark every component with "use client" because they are used to React. But when you do this, the browser has to hydrate everything. This means more JavaScript, more parsing, more work for the browser.

I realised this when I saw a simple page taking more than 2 seconds to get interactive.

Fix. Use client components only when you need things like state, event handlers, or browser APIs. Everything else can stay as Server Components.

Example of what should be a server component.

export default function ProductPrice({ price }) {
return <p>Price. {price}</p>;
}

There is no need for it to be a client component.


6. Extra API calls inside Server Components

A lot of people including me made this mistake when switching to the App Router. We fetch data in a Server Component but instead of calling the function directly, we hit our own API route.

For example.

const data = await fetch("/api/products");

This still creates a network request. Slower. Unnecessary.

Fix. Call your backend logic directly.

import { getProducts } from "@/lib/db";

const products = await getProducts();

No extra network hop. Much faster.


7. Over rendering due to poor component organisation

Sometimes page components hold too much state. That state changes. And now the entire tree re-renders. Even parts that do not need to.

For example. You store a search query in the parent. Every time the user types one character, the whole layout re-renders including header, footer, sidebar and everything.

Fix. Move state closer to where it is used. Or isolate sections using React.memo.

Example.

const Sidebar = React.memo(function Sidebar() {
return <div>Sidebar menu</div>;
});

This prevents unnecessary re-renders.


8. Ignoring layouts and repeating code

Before I fixed this, I used to repeat the same header and footer on every page. This created more JavaScript to hydrate and slowed down navigation.

Next.js App Router gives you a layout.js that wraps pages. But many beginners do not use it.

Fix. Move all common UI like navbars, sidebars, branding, containers into the layout file. Then page transitions become very fast because only the inner content updates.


9. Not analysing your bundle or performance

It is easy to think everything is fast because it opens quickly on your laptop. But not everyone uses a fast device. Your users might be on a 4G network or an older phone.

One time I tested a site on my phone and it took 6 seconds to load. But on my laptop it looked perfectly fine.

Fix. Always run audits. You can use Chrome DevTools. Check network waterfall. Check how large your JavaScript bundle is.

In Next.js you can add a bundle analyser.

const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: true,
});

When you see a file that is too large, break it into smaller parts.


10. Ignoring mobile performance

This is a silent killer. Everything works great on desktop but the moment you switch to mobile. Lag. Freeze. Slow scroll. Layout shifts everywhere.

A common example is using animations or libraries that are heavy. On desktop it is smooth. On mobile it stutters.

Fix. Test your app on mobile. Always. Open DevTools. Throttle the network to Slow 3G. If the page takes more than 2 seconds to show something, optimise.

• Use smaller images

• Remove unused JavaScript

• Lazy load non essential components

• Avoid blocking the main thread

Mobile users should see something quickly. Even a skeleton loader is better than a blank screen.


Final Thoughts

Next.js gives you a lot of power. But if you do not use the features properly, your app will feel slow. The good part is these are small mistakes. You can fix them one by one. None of them require a full rewrite.

When you avoid these mistakes, you get a faster app. Better SEO. Better user experience. And for freelancers like us, it makes our projects look more polished and professional.

If you want, I can also convert this blog into a short video script or LinkedIn post.

nextjs mistakesnextjs performancenextjs speednextjs optimizenextjs slow fiximprove nextjs speednextjs tipsnextjs best practicesnextjs beginnersnextjs common errorsnextjs loading slownextjs optimisation guidenextjs server componentsnextjs image optimizationnextjs bundle sizefaster nextjs appsnextjs seo tipsnextjs quick fixesnextjs app slowboost nextjs performance

Recent Blogs

View All