How to Speed Up and Optimize Your Next.js Website or Blog for Faster Page Load

In my previous post, I talked about improving the responsiveness of my Next.js website by adding a progress bar.

This helped by letting users know something was loading and made the site feel more responsive.

You can read about it here: How to Add a Progress Bar to Your Next.js App for Better User Experience.

However, while a progress bar can reduce bounce rates caused by perceived slowness, it doesn’t fix the actual speed of the site.

When I first developed my blog, it took longer to load than I expected.

I did some digging to figure out why my Next.js blog loaded slowly and found a few optimization techniques.

These steps may not make the site perfect, but they’ve improved things a lot, and I’m okay with the results for now.

Here’s what I did to optimize my website and make it load faster:

1. Optimize Images Using Next.js Image Component

Images play a huge role in website speed. Thankfully, Next.js has a built-in Image component that optimizes images out of the box.

It automatically resizes images to fit the user’s screen size and lazy-loads them.

For instance, if the original image is 800x400 pixels but the user’s screen only displays 360x180 pixels, the image is resized dynamically to match that size.

Here’s how you can use the Image component:

import Image from "next/image";

<Image
  src="/path-to-image.jpg"
  alt="Description"
  width={800}
  height={400}
  loading="lazy"
/>;

Additionally, I recommend reducing the size of your images before uploading them. Even though Next.js will handle optimization, tools like TinyPNG for PNGs, TinyJPG for JPEGs, or FreeConvert can compress your images and reduce their size without compromising quality.

For example, a 1MB image can be reduced to just a few KB, which saves bandwidth and makes your site faster.

2. Dynamically Import Heavy Components or Libraries

Some components and libraries don’t need to load immediately. Importing these dynamically ensures they only load when required, reducing the initial page load time.

For example, let’s say you have a heavy animation library or component. Instead of importing it normally, you can import it dynamically like this:

import dynamic from "next/dynamic";

const AnimationComponent = dynamic(() =>
  import("@/components/AnimationComponent").then((mod) => mod.default)
);

Here’s another example from my blog where I dynamically import a BlogPageHero component:

const BlogPageHero = dynamic(() =>
  import("@/components/Blog/BlogPageHero").then((mod) => mod.default)
);

I also use dynamic imports for MDX components, which render blog content, because they are a bit heavy. This approach keeps the initial load light and improves performance.

3. Tree-Shake Your Imports

If you’re importing entire libraries, you might be adding unnecessary weight to your app. Instead, drill down to the specific module or function you need.

For example:

// Less efficient
import { format } from "date-fns";

// More efficient
import format from "date-fns/format";

By doing this, you only load what you actually need, making your code lighter and faster.

💡 Pro Tip: Install the “Import Cost” extension in VS Code. It helps you see the size of imported libraries and identify potential optimization opportunities.

Import Cost extension in VS Code

4. Pre-render Dynamic Routes Using generateStaticParams

If your site has dynamic routes, like /blog/[slug]/page.tsx for blog posts, you can pre-render these pages at build time using generateStaticParams. This ensures the pages load much faster for users because most of the HTML content is already generated.

Here’s an example:

export async function generateStaticParams(): Promise<
  { params: { slug: string } }[]
> {
  return allBlogs.map((blog) => ({ params: { slug: blog.slugAsParams } }));
}

This works well with the latest Next.js App Router. For those using the old Pages Router, you can achieve the same results using getStaticProps and getStaticPaths.

5. Use Optimized Fonts with Next.js

Next.js fonts are optimized for performance and designed to load quickly. By using them, you can reduce font loading times and improve your page speed.

Wrapping up

With these steps, I was able to significantly improve my blog’s load times and user experience.

While the site might not be perfect yet, the changes made a noticeable difference, especially when it comes to reducing bounce rates and improving performance.

If you’ve been struggling with a slow-loading Next.js site, give these tips a try.

They worked for me, and I hope they’ll help you too! If you find this useful then kindly share.