CSR, SSR, and SSG on NextJS
NextJS 9.3 brings Static Site Generation to the NextJS platform. Which is really exciting because NextJS now supports three different rendering modes.
- Client Side Rendering (CSR)
- Server Side Rendering (SSR)
- Static Site Generation (SSG)
This article explains these three modes and when to use them. If you like video better you should check out this companion video.
Client Side Rendering
Client side rendering, or CSR, is the most common way of rendering React apps. It's what you get out of the box if you are using Create React App. The lifecycle is very simple. The server renders a blank page with a script tag pointing at the React app's bundle. That page is then sent to the client which renders the blank page, and starts to run the app. The React app then makes whatever API calls it needs to and renders the contents of the page.
This is also how NextJS by default, renders the page, assuming you do not have a getServerSideProps
method exported from your page.
Pros
- Fast on the server - Because you are only rendering a blank page it's very fast to render.
- Supports static - The blank page can be statically generated and served from something like S3, which makes it even faster.
- Supports Single Page Applications - Client Side Rendering is the only model that supports Single Page Applications, or SPAs.
Cons
- No initial render - You are sending a blank page to the customer. So if your app is big, or the customer is on a slow connection, that's going to be less than ideal.
Server Side Rendering
In the Server Side Rendering model the NextJS server first calls the getServerSideProps
method exported from your page file. This method returns props which are then sent to the component. The server renders the page component with those props and it converts that to an HTML string which it sends back to the client.
NextJS also takes the returned props from getServerSideProps
and send that to the client as well for a process called hydration.
On the client side the browser gets the HTML payload and renders out the page contents. It then starts parsing and running the React app in the Javascript bundle. The React app then hydrates from the state that NextJS stored for you. Your application initializes and you are off to the races.
Pros
- Content immediately available - Because you are sending rendered HTML to the client the customer will start to see content almost immediately.
- No additional client fetches - Ideally the server rendering process will make all the required calls to get the data, so you won't be making any additional service calls from the client. At least until the user starts to play around with the page a little.
- Great for SEO - Search engines like HTML content. If you are using client side rendering only then you are counting on search engines running your Javascript, which may or may not happen.
Cons
- Slower on the server - You are rendering the page twice, once on the server and once on the client. You are also probably making service calls from the server to render the page. All of that takes time so the initial send of the HTML to the client could be delayed.
- Incompatible with some UI libraries - If the UI library you like uses window then you are going to need to fix that or use something else because Node doesn't have
window
ordocument
.
Static Site Generation
Static Site Generation is like Server Side Rendering with the exception that you render the pages at build time instead of at request time. In the Next world that means that the NextJS build process first calls the getStaticPaths
method exported from your page Javascript file to get an inventory of all the routes it should render. The build process then calls the getStaticProps
method for each of the routes and renders the page the same way it does in Server Side Rendering.
At the end of the build process you then have a set of HTML files that you can then host on a static hosting service and you have a site that you no longer need a server to run.
Pros
- Content immediately available - Because you are sending rendered HTML to the client the customer will start to see content almost immediately.
- No additional client fetches - Ideally the server rendering process will make all the required calls to get the data, so you won't be making any additional service calls from the client. At least until the user starts to play around with the page a little.
- Great for SEO - Search engines like HTML content. If you are using client side rendering only then you are counting on search engines running your Javascript, which may or may not happen.
- Incredible Fast To Serve - Static content is crazy fast to serve. You can also edge cache it very cleanly.
- No Server - You don't have to run a server. So you don't need to monitor that server and you are going to get far less pager duty pings.
Cons
- Can be slow to rebuild large sites - If you have tens of thousands of routes you should expect slowdowns. Though the NextJS team is working on incremental rebuilds.
- Incompatible with some UI libraries - If the UI library you like uses window then you are going to need to fix that or use something else because Node doesn't have
window
ordocument
.
How To Choose
Here are some heuristics I use.
- Logged in experiences - If your experience requires a login to view the content and it's customize per user (e.g. Settings Pages, Bank Accounts, etc.) then Client Side Render.
- Public content - If the target experience is a content site, then Server Side Rendering, or even better Static Site Generation.
- Single Page Applications - If your site is a SPA then you should use Client Side Rendering.
- SEO is a major requirement - If your pages need to be traversable by search engines then use Server Side Rendering or Static Site Generation if it fits the model.
- Slow moving content - If you have content that doesn't move quickly, like a product catalog, or a content site with articles, then Static Site Generation is a great alternative for that. And if you have parts of the page that do move quickly, like comments or recommendations, then you can use a Micro-FE strategy to bring in that content while still getting the advantages of Static Site Generation.
Conclusion
NextJS is amazing in its own right, but the addition of Static Site Generation in 9.3 means that you can mix and match any of these rendering modes to suit your requirements without having to change frameworks. It's great stuff, you should try it out, or better yet, follow along with the video and the associated code and see for yourself.