Making dynamic pages fast in Next.js

8/12/2025

The main reason for the use of Next.js instead of a traditional SPA type framework, is of course the benefit of having server side rendering. This will save you from having the user see a lot of loading spinners, and instead just giving them the HTML in the request. But my only issue with this is, that actually clicking and navigating to the rendered page takes long and feels sluggish.

Why does it feel sluggish/slow?

The main reason for it being slow is that its fetching and computing all the necessary data for the page. This means that it sends request(s) to the database, performing data mutations and parsing HTML, to eventually send it back to the client. Any time you are doing extra steps, it takes extra time. This is ultimately my issue with server side rendering, while it is nice for SEO purposes, it feels slow.

How do you solve this?

In Next.js this can easily be solved with a function export inside the page route (in the app router in next v15.3.5). This function is called "generateStaticParams". What this function does, is at build time generate the HTML for the params that are returned. This function has to reside inside a dynamic route, like: "/blog/[slug]/page.tsx" for example.

export async function generateStaticParams() {
  const posts = await getBlogPosts();

  console.log("Generating static params for blog posts:", posts);

  return posts
    .map(post => ({ slug: post.slug }));
}

Now we are introducing another problem: If the dynamic routes change, like in this example a post gets added or deleted, what happens? In this case the static params will be stale. This is because the server sends out the HTML from the time of the build, which is not representative of the current state. This is something we definitely do not want to happen in a production environment.

Revalidating Routes

To prevent a route from becoming stale, the page should be rerendered. Next.js has a neat function to allow for asynchronous revalidating! Using the "revalidatePath" function you can regenerate a path by specifying a route by string.

So for example if we update, delete or add a new post in an endpoint, we simply call the revalidatePath function with the proper path like this:

const post = await publishBlogPost(id);
revalidatePath(`/posts/${post.slug}`);