Understand SSG, ISR, and SSR Rendering Methods used in Next.js

Lazar Nikolov
InstructorLazar Nikolov
Share this video with your friends

Social Share Links

Send Tweet

There are three main ways that you can render in a Next.js application: pre-render with server-side rendering (SSR), pre-render with static site generation (SSG), or updating/creating content at runtime with incremental static regeneration (ISR).

This lesson dives into the theory of these three methods before jumping in to the implementation of these methods in Next.js. You’ll learn the benefits and constraints of each method. For implementation of these methods, check out: Statically Generate Pages through SSG and ISR with Next.js getStaticProps or Dynamically Generate Next.js Pages with Server Side Rendering using getServerSideProps (the next two lessons!).

Instructor: [0:00] Data fetching in Next.js allows you to render your content in different ways, depending on your application's use case. These include pre-rendering with server-side rendering or static generation, and updating or creating content at runtime with incremental static regeneration.

[0:18] Next.js gives you the possibility to use different rendering methods for each page individually, as opposed to using SSR or SSG for your whole website. In this lesson, we're going to explain the concepts of SSG, SSR, and ISR, and how they work.

[0:35] In the next two lessons, we're going to see how to actually implement them in our Next.js app. Let's begin. Let's start with static generation. Before we dive in, let's learn how this diagram works.

[0:49] The database server, your computer, and the browser are called actors. These represent all of the moving parts in our app. These lines that you see here are the process lines. As you can see, they also have a number assigned to them, which is the order of the execution.

[1:08] In SSG or static generation, it starts with your computer or the CI/CD machine. Let's say you run npm run build. Next.js will then query the necessary data from the database for every page.

[1:21] After it has the data, it will build the Next.js project and prepare it for production. When that's done, you can deploy the bundle to the server. That server can be your own dedicated Linux server or a CDN like Vercel.

[1:37] After you deploy your website, it is now live and users will be able to visit it. That's when the browser comes into play. The browser actor is the user, regardless of where the user is accessing your website from. It can be a laptop or a mobile phone, etc.

[1:53] A user lands on your page, it will request the website from the server, in this case, let's say Vercel. Since Vercel has the bundle that you deployed, it will immediately return the pre-built website. This will happen for every next user.

[2:08] It will request the website and Vercel is going to return the pre-built website. The good sides of this static generation method is that the websites are super fast. There is little or no JavaScript involved. The data is already pre-fetched.

[2:22] When the browser receives the package from the server, it can start to render the page immediately. The downside of this method is that we have static data. As you can see on this side, the data gets updated only when we run npm run build.

[2:37] There is no connection between the server and the database. If you update your data, you will need to run npm run build again to obtain the new data, rebuild your Next.js project, and deploy the new bundle.

[2:50] After that, the users will be able to access the new data. That's how SSG works. Let's move onto the server side or SSR. As you can see, it's pretty similar to SSG, but the database is connected with the server as opposed to your computer. Let's start.

[3:07] First, you run npm run build, and you build your Next.js project. After you've done that, you deploy the bundle to the server. After you've deployed the bundle to the server, your website is live and can be accessed.

[3:21] A user comes in and requests your website. This time, instead of returning the pre-built website immediately, the server will first query the data from the database, generate the HTML for that page with that data, and then return the pre-built website.

[3:37] If another user lands on your page, the server will again query the data, generate the HTML, and then return the pre-built website.

[3:46] As opposed to the previous method, we now have live data meaning if we add something to our database, it will be immediately available on our website because the server generates the HTML for each request. If 1,000 users land on our website, the server will query the database and generate the HTML 1,000 times.

[4:06] The good side of this method is that we have dynamic data, but the bad side of this method is that our server is going to have to work much harder than the previous method. It will need to query the database and generate new HTML every time a user lands on the page.

[4:23] Another downside of this method is that the browser will need to wait for the server to query the data and generate the HTML, and then return the pre-built website to the browser, even though nothing has changed from the previous request.

[4:38] That is server-side rendering. Now, let's move on to the ISR or incremental static regeneration. As you can see, this is a hybrid between the SSG and SSR. We have connections to the database from both, our computer and the server.

[4:53] Let's see how this works. When we run npm run build, the Next.js server will query the necessary data from the database and then build the Next.js project. As soon as that's done, we deploy the bundle to our server, but this time, it's marked with version one.

[5:09] Let's say a user lands on our website. It will request the website, and then the server will return the version one immediately because it already has that one. In the meantime, the server will query the page data from the database in case there is new data.

[5:26] It will regenerate that page and overwrite the old version as version two. It will continue to serve that one. When the next user comes in, they will request the website, but the server will immediately return version two of the website.

[5:42] The same thing will happen again. After the second user, the server will query the page data from the database. It will regenerate if there is new data as version three, and it will continue to serve version three from that point on.

[5:58] Even though this looks like SSR, querying the data, regenerating the page on every request, it doesn't actually happen on every request. In Next.js, we can configure a timeframe in which a certain page will be regenerated maximum one time.

[6:15] For example, if we set the revalidation or regeneration of the page to one hour, it will only regenerate the page once within that hour. The first user lands on our website, query the page data, regenerate the page, and keep serving that one.

[6:30] Every other user that lands on our website within the next hour will receive version two, but they will not trigger the query the page data and the regenerate the page process flows.

[6:43] That's how incremental static regeneration or ISR works. The benefits of this method is, just like the SSG method, we get static data and we return it to the user immediately. We get the speed of static generation.

[6:57] We also have dynamic data because the server will periodically query the database and regenerate the page if there is demand for it without us having to rebuild the Next.js project and deploy the newer version.

[7:10] Those are the three data-fetching methods in Next.js. Let's recap. We learnt about static generation or SSG, where the page gets generated when we run npm run build. All of the necessary data is queried from the database.

[7:28] The Next.js project gets rebuilt, and we deploy it on the server. The server will then serve the bundle that we deployed. We had faster response rates, but no dynamic data. Then we learnt about the server-side rendering or SSR, where pretty much the same thing happened.

[7:49] We built the Next.js project and deployed the bundle, but the server queried the database and generated the HTML on every request. We had slower response rate, but we had dynamic data.

[8:03] Then we learned the incremental static regeneration method, where we generated some initial data, rebuilt the project and deployed the version one on our server. The server then immediately returns version one to our users, but in the meantime, queried the database, regenerated the data and continued serving version two.

[8:23] This way, we had the response speed of static and also dynamic data of server side.