Static Site Generation vs. Server-Side Rendering in Next.js

Published On
Posted

What are Static Site Generation (SSG) and Server-Side Rendering (SSR) in Next.js and how do they compare?


Next.js logo

Next.js SSR vs SSG

Introduction

In the rapidly evolving landscape of web development, Next.js has emerged as a powerful framework for building React applications. One of the key decisions developers face when working with Next.js is choosing between Static Site Generation (SSG) and Server-Side Rendering (SSR) modes for rendering pages. Both methods have their advantages, but understanding when to use each can significantly impact the performance and scalability of your application. This blog post will dive into the differences, benefits, and use cases of SSG and SSR in Next.js, providing clear examples and performance comparisons to help new developers choose the right approach.

What are Static Site Generation (SSG) and Server-Side Rendering (SSR)?

Static Site Generation (SSG)

Static Site Generation (SSG) involves pre-rendering pages at build time, producing static HTML files for each page. This approach is ideal for content that does not change frequently, as the static files can be served quickly and efficiently from a Content Delivery Network (CDN). The main advantage of SSG is its performance, as pre-rendered pages load faster and require fewer server resources.

Server-Side Rendering (SSR)

Server-Side Rendering (SSR), on the other hand, generates dynamic HTML on the server for each request. This method is suitable for dynamic content that changes frequently, ensuring that users always receive the most up-to-date information. While SSR can be slower than SSG due to the need for server-side processing, it is essential for applications where content personalization and real-time up to date data are critical.

Differences between SSG and SSR in Next.js

Build Time vs. Request Time

The primary difference between SSG and SSR lies in when the pages are generated:

  • SSG: Pages are generated at build time.
  • SSR: Pages are generated on each request.

Performance

  • SSG: Faster since pages are served from CDN.
  • SSR: Slower as it involves server processing for each request.

Use cases

  • SSG: Suitable for blogs, documentation, marketing pages.
  • SSR: Suitable for e-commerce sites, user dashboards, real-time data applications.

Benefits of SSG and SSR

SSG

  • Improved performance: Pre-rendered pages are served quickly from a CDN.
  • Better scalability: Reduced server load as only static files are served.
  • Enhanced Security: No server-side code execution, reducing attack vectors.

SSR

  • Dynamic Content: Ensures users receive the latest and fresh data on each request.
  • User-Specific Content: Tailors content to individual users.
  • Real-Time Updates: Ideal for applications requiring real-time data.

Use Cases for SSG and SSR

SSG Use Cases

  • Blogs And Personal Websites: Static content that rarely changes.
  • Documentation Sites: Pre-rendered pages provide quick access.
  • Marketing and Landing Pages: Fast loading times for improved SEO and user experience.

SSR Use Cases

  • E-commerce Sites: Frequently changing product data.
  • User-Specific Dashboards: Personalized content for users.
  • Real-Time Applications: Data that needs to be up to date on each request.

Performance Comparisons

SSG

  • Load Time: Generally faster due to pre-rendered static files.
  • Server Load: Lower server load since pages are served from CDN.

SSR

  • Load Time: Slower compared to SSG as each request requires server processing.
  • Server Load: Higher server load due to rendering on each request.

Practical Examples

Let's now examine some practical examples with code snippets showcasing how to implement both SSG and SSR in a Next.js application.

SSG Example in Next.js 14 using App Router with dynamic and revalidate

Here's an example of using SSG with the new Next.js 14 App Router. This code snippet demonstrates how to generate static pages and revalidate them periodically.

page.js
js
// app/posts/[id]/page.js import React from "react"; import { promises as fs } from 'fs'; import path from 'path'; // Fetch data at build time export async function generateStaticParams() { const filePath = path.join(process.cwd(), 'data.json'); const jsonData = await fs.readFile(filePath, 'utf8'); const data = JSON.parse(jsonData); return data.items.map(item => ({ id: item.id })); } // Dynamic and revalidate option for incremental static regeneration export const dynamic = 'force-static'; // Revalidate at most once every 60 seconds export const revalidate = 60; // Page component export default async function PostPage({ params }) { const filePath = path.join(process.cwd(), 'data.json'); const jsonData = await fs.readFile(filePath, 'utf8'); const data = JSON.parse(jsonData); const post = data.items.find(item => item.id === params.id); return ( <div> <h1>{post.title}</h1> <p>{post.content}</p> </div> ); }

In this example:

  • generateStaticParams generates the static paths for each post at build time.
  • dynamic = 'force-static' ensures that the page is statically generated.
  • revalidate = 60 enables incremental static regeneration, updating the static page at most once every 60 seconds.

SSR Example in Next.js 14 using App Router with dynamic

Here's an example of using *SSR with the new Next.js 14 App Router. This code snippet demonstrates how to fetch data on each request and render the page server-side.

page.js
js
// app/posts/[id]/page.js import React from "react"; // Dynamic option to force server-side rendering export const dynamic = 'force-dynamic'; // Page component export default async function PostPage({ params }) { const res = await fetch(`https://api.example.com/posts/${params.id}`); const post = await res.json(); return ( <div> <h1>{post.title}</h1> <p>{post.content}</p> </div> ); }

In this example:

  • dynamic = 'force-dynamic' ensures that the page is server-side rendered on each request.
  • The PostPage component fetches the post data based on the id parameter and renders it dynamically.

Conclusion

Choosing between Static Site Generation (SSG) and Server-Side Rendering (SSR) in Next.js depends on the specific needs of your application. SSG offers superior performance and scalability for static content, while SSR provides dynamic, real-time data crucial for certain use cases. By understanding the differences, benefits, and appropriate use cases, you can make an informed decision that optimizes both user experience and application performance.