Rendering Strategies in Next.JS

Wanuja Ranasinghe
Dev Genius
Published in
12 min readSep 22, 2023

--

Detailed explanation of CSR, SSR, SSG, and ISR with examples.

Rendering Strategies in Next.js
Figure 1: Rendering Strategies in Next.Js

Next.js is built on top of React.js and we can do everything we do in React.js. Additionally, it provides many features such as a built-in routing system, automatic code splitting (splits our code into smaller chunks which reduces the size of JavaScript bundle), different data fetching mechanisms, improved developer experience (automatic optimization of assets) and it helps to build SEO-friendly applications. In this article, I am focusing on the data fetching mechanisms of Next.js with their advantages and disadvantages and the situations where we need to choose one over the other.

In this demonstration, I showcase the implementations of different rendering strategies using the App Router in Next.js. While it is currently possible to use both the App Router and the Pages Router to create Next.js applications, it is advisable to prefer the App Router due to its design for greater flexibility and efficiency compared to the Pages Router. Furthermore, there is a possibility that the Pages Router may be deprecated in the future. The links for the source code and demonstration are included at the end of the article. Let’s delve into today’s content.

Next.js provides four rendering strategies. Such as,

· CSR — Client-Side Rendering

· SSR — Server-Side Rendering

· SSG — Static Site Generation

· ISR — Incremental Static Regeneration

Client-Side Rendering (CSR)

Client-side rendering (CSR) is a method for rendering web content in which the web browser requests data from the server and then renders the page by executing JavaScript code in the browser. In other words, the web page is entirely created and rendered on the client side, meaning that the server only sends the raw data and client-side code manages the rendering and display of the page. Client-side rendering involves the server sending the HTML, CSS, and JavaScript files to the browser, which then renders the page. The JavaScript code must retrieve the data and update the DOM (Document Object Model) with the data.

Illustration of Client Side Rendering
Figure 2: Client Side Rendering

Here’s a more detailed explanation of the above figure 2.

Step 1: A user makes a request for a web page by entering the URL into their browser or clicking on a link.

Step 2: The server sends bare-bones HTML and JavaScript as a response.

Step 3: The browser loads static resources, like CSS and images, which are needed to show the page.

Step 4: JavaScript execution: If the page is built using client-side rendering, the browser will also download and execute a JavaScript file that contains the code for the client-side framework or library.

Step 5: Data fetching: The JavaScript code may make API calls to retrieve data that is needed to render the page. This data can come from a server-side database, a third-party API, or any other source.

Step 6: Render the page: Using the data that has been fetched, the JavaScript code generates the HTML for the page and updates the DOM to reflect the changes. This is done dynamically, meaning that the HTML is generated on the fly in response to user interactions or other events.

Step 7: The browser updates the view according to the changes made to the DOM.

When to use Client-Side rendering

CSR has its own set of use cases and is well-suited for certain scenarios where dynamic, interactive, or real-time capabilities are essential.

Examples: Gaming and Multimedia Applications, Interactive Forms and Surveys, Data Dashboards, and other applications that need real-time updates.

Here are some of the benefits of using client-side rendering:

  • Faster initial load time: The browser can start rendering the page as soon as it receives the HTML, CSS, and JavaScript files. This can lead to a faster initial load time, which is important for improving the user experience.
  • Better interactivity: CSR allows for better interactivity, as the browser can update the page dynamically in response to user input. This is essential for web applications that require a lot of user interaction.
  • Easy to develop: CSR is easier to develop than SSR, as you do not need to worry about server-side rendering. This can save you time and effort.

However, CSR also has some drawbacks, like:

  • Poor SEO: CSR can impact SEO, as search engines cannot crawl and index the rendered HTML pages.

Implementation:

Client-Side Rendering Implementation

Here is a breakdown of the code:

  • The use client directive at the top of the file disables server-side rendering for the component and it enables client-side rendering.
  • The useState hook is used to create a state variable called dateTime. This state variable will store the current date and time.
  • The useEffect hook is used to fetch the current date and time from the World Time API and update the dateTime state variable.
  • The TimeCard component is passed the dateTime state variable as a prop.
  • The TimeCard component can then use the dateTime prop to display the current date and time to the user.

Server-Side Rendering (SSR)

Server-side rendering (SSR) is a technique where the web server renders HTML, CSS, and JavaScript for a web page before sending it to the client (usually a web browser). The server generates the entire HTML content for a web page and sends it to the client as a fully-formed web page using SSR. The client then receives the HTML content, as well as any associated CSS and JavaScript, then we will have an interactive web page by executing JavaScript.

Illustration of Server Side Rendering
Figure 3: Server Side Rendering

Here’s a more detailed explanation of the above figure 3.

Step 1: A user makes a request for a web page by entering the URL into their browser or clicking on a link.

Step 2: The Browser sends a GET request to the server.

Step 3: The server receives the request and determines which page the user wants to see based on the URL and then the server starts to retrieve the data needed to render the page.

Step 4: The server sends API calls to fetch the data from various resources. The data can come from server-side databases, a third-party API, or any other source.

Step 5: The server renders the page using a server-side rendering framework, such as Next.js. This framework generates the HTML, CSS, and JavaScript for the page on the server, using the data retrieved in the previous step.

Step 6: The server sends the generated HTML, CSS, and JavaScript to the Client (Browser).

Step 7: The browser parses the HTML and renders the page. The browser then executes the JavaScript code, which can be used to make the page interactive (The browser updates the view according to the changes made by the client-side JavaScript code).

When to use Server-Side Rendering

Server-side rendering (SSR) is especially useful for pages that contain a lot of dynamic content or that are frequently requested by users.

Examples: Content-Heavy Websites and Blogs, E-commerce Platforms, Progressive Web Apps (PWAs), Multilingual Websites, Content Management Systems (CMS), and SEO-Critical Pages.

Here are some of the benefits of using server-side rendering:

  • Improved performance: SSR can significantly improve the performance of web pages by reducing the amount of work that the browser has to do. This is because the browser does not have to render the page from scratch but instead receives a pre-rendered HTML page from the server.
  • Better SEO: SSR can help improve the SEO of your website by making your pages more accessible to search engines. This is because search engines can crawl and index the rendered HTML pages, which can help your pages rank higher in search results.
  • Better accessibility: SSR can also help improve the accessibility of your website for users with disabilities. This is because the rendered HTML pages can be easily parsed by screen readers and other assistive technologies.

However, there are also some drawbacks to using server-side rendering:

  • Increased server load: SSR can increase the load on your servers, as the server has to render the pages on every request. This can be a problem if you have a lot of traffic or if your servers are not powerful enough.
  • More complex development: SSR can make development more complex, as you need to take into account the fact that the pages are being rendered on the server. This can make it more difficult to test and debug your code.

Implementation:

Server-Side Rendering Implementation

The cache: 'no-store' option in the getDateTime() function prevents the response from being cached by the browser or any other intermediaries. This means that the getDateTime() function will always fetch the latest date and time from the World Time API, even if the user has already visited the page before.

Static-Site Generation(SSG)

The Static Site Generation (SSG) method involves generating all the HTML, CSS, and Javascript files during the build time of an application. This means that during the build time, all the necessary data will be fetched from relevant resources. Once the application is built using the Static Site Generation (SSG) method, the web pages will not be generated for each request. This approach is different from dynamic rendering, where the server generates HTML content for each request.

So, SSG is a technique that enables faster website load times and better SEO performance by pre-rendering web pages during build time. This approach reduces the amount of processing required on the server side and results in a better user experience.

Illustration of Static Site Generation
Figure 4: Static Site Generation

Here’s a more detailed explanation of the above figure 4.

Step 01: The Production build runs after writing the code with the help of a static site generator, such as Next.js. The production build can be done within the development environment or some servers like Vercel, and Netlify, and those servers run the production build on their infrastructure. (In Figure 4 I showed the production build inside the dev environment)

Step 02: The static files generated in the previous step are then deployed to a web server. This can be a cloud-based server, such as Vercel or Netlify, or a self-hosted server.

Steps 03 & 04: A user makes a request for a Web page by entering the URL into their browser or clicking on a link.

Step 05: The server sends the HTML, CSS, and JS files to the web browser, and then the browser executes the JavaScript code in the web page, which renders the interactive elements of the page.

Step 06: The browser displays the interactive web page to the user.

When to use Static-Side Generation

Static site generation (SSG) can be used for any website that has static content that does not change frequently.

Examples: Blogs, Portfolios, Documentation sites, Marketing sites, Static landing pages

Here are some of the benefits of using SSG:

  • Faster loading times: Since the static files are generated at build time, they are already cached by the browser when a user visits the website. This can significantly improve the loading times of your website.
  • Better SEO: Since the static files are generated at build time, they can be indexed by search engines more easily. This can help improve your website’s search engine ranking.
  • Scalability: Static site generators are typically very scalable, so they can handle a large number of visitors without any problems.
  • Cost-effectiveness: Static site generators can be a cost-effective way to build and maintain a website.

However, there are also some drawbacks to using SSG:

  • Not suitable for dynamic content: If your website has a lot of dynamic content that changes frequently, then SSG may not be the best choice.
  • Limited interactivity: Static site generators can be limited in terms of the interactivity they can provide. For example, they may not be able to handle real-time chat or other interactive features.
  • Complex development process: The development process for SSG can be more complex than the development process for other types of websites. This is because you need to make sure that all of the data that is used to render the static pages is available at build time.

Implementation:

Static Site Generation Implementation

The cache: 'force-cache' option in the fetch() function tells the browser to cache the response from the World Time API. This means that the getDateTime() function will only fetch the data from the API on the first build, and then it will use the cached data on subsequent builds.

Incremental Static Regeneration (ISR)

Incremental Static Regeneration is a technique that combines aspects of both Static Site Generation(SSG) and Server Side Rendering(SSR). Similar to SSG, the application is built during the initial build time, and we include some time duration(Time-based revalidation) and conditions(On-demand revalidation) to rebuild a certain page or a section for fetching the data once again from the resources like in SSR.

Illustration of Incremental Static Regeneration
Figure 5: Incremental Static Regeneration

Here’s a more detailed explanation of the above figure 5.

I’ve shown two different scenarios about how people use a webpage. Imagine this: first, the server is going to build the application at a specific time, let’s call it ‘t1.’ We’ve also decided that we want to update or recreate this webpage every so often, like ‘x’ units of time. So, every (t1 + x) time, the server makes a brand new version of the webpage (suppose this is version 1).

Now, picture this: a user decides to visit a particular webpage for the very first time at a time called ‘t2.’ This happens somewhere between ‘t1’ and (t1 + x). During this time, they’ll see version 1 of the webpage. That’s because version 1 was the latest one during this time frame.

As time moves on to (t1 + x), the server starts the process of making a fresh build of the webpage. So, anyone who visits the webpage after this point gets version 2. To make it clearer, if a user comes back to the same page after this update, they’ll see version 2.

When to use Incremental-Static Regeneration

ISR generates pages on-demand, which allows for updates to specific pages or sections of a page without regenerating the entire site. ISR is particularly useful for large websites, e-commerce sites, and news websites that require frequent updates. By using ISR, these websites can achieve a balance between dynamic content and pre-rendering for faster load times and better SEO performance.

Here are some of the benefits of using ISR:

  • Reduced load on your backend: ISR can help to reduce the load on your backend by serving static pages instead of dynamic pages. This is especially important for sites with high traffic.
  • Improved scalability: ISR can help to improve the scalability of your site by allowing you to generate static pages for millions of pages.
  • Better SEO: ISR pages can be indexed by search engines more easily than dynamic pages, which can lead to improved SEO rankings.
  • Improved user experience: ISR pages can provide a better user experience by delivering faster page load times and a more consistent experience across all users.

However, there are also some drawbacks to using SSG:

  • Increased build time: ISR pages can increase the build time of your Next.js site because Next.js needs to generate a static page for each ISR route.
  • Limited use cases: ISR is not suitable for all types of pages. For example, you would not want to use ISR for pages that contain user-specific content, such as a user’s profile page.
  • Inconsistent experience: If the data that an ISR page relies on changes, the page will not be updated until the next time it is revalidated. This can lead to an inconsistent experience for users, who may see an outdated version of the page.

Implementation:

Incremental Static Regeneration Implementation

The next: { revalidate: 20 } option in the fetch() function tells Next.js to revalidate the static content every 20 seconds. This means that Next.js will fetch the latest data from the World Time API every 20 seconds and update the static content accordingly. Because of this, ISR is a good balance between SSR and SSG. It allows you to serve static pages that are always up-to-date, without having to rebuild the entire site on every request. This can improve the performance and scalability of your application.

Conclusion

Next.js offers four rendering approaches: SSG, SSR, ISR, and CSR. Each approach has its own benefits and drawbacks, so it is important to choose the right approach for your specific needs.

When choosing a rendering approach, consider the following factors:

  • Content type: Is the content static or dynamic?
  • Performance: How important are fast page load times?
  • SEO: How important is SEO to your application?
  • Complexity: How complex is the user interface?

Choose the rendering approach that best meets your needs.

Thanks for reading ❤️.

Demonstration 🌎

https://rendering-strategies-in-nextjs.vercel.app/

Source Code 👩🏻‍💻

https://github.com/Wanuja97/rendering-strategies-in-nextjs

References 📌

01)Data Fetching Patterns — https://nextjs.org/docs/app/building-your-application/data-fetching/patterns

02) Fetch & Caching options — https://nextjs.org/docs/app/api-reference/functions/fetch

03)App Router Incremental Adoption Guide — https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration

--

--