SSR & SSG
When setting up an application from scratch with just React all rendering will happen in the browser. Not before all JavaScript is loaded the browser will start with this. Because of this, it will take longer before the user can start using the application. Lighthouse, a tool for analyzing performance, accessibility, and more, is calling this "Time to Interactive". The higher this metric, the poorer the User Experience.
Another disadvantage of an application that's being rendered in the browser is that it's harder for crawlers of search engines to index such applications. Crawlers are somewhat outdated and primarily process content that's being rendered in the back-end. This behavior originates from the time that a front- and back-end weren't decoupled and connected with an API. Websites and web apps were rendered on the server and then presented to the user. Back then, JavaScript was primarily used to enhance the behavior, not to write entire applications.
Server-side Rendering (SSR)
With Server-side Rendering, the first render of an app will be done on the server-side. It will fetch all data, render the app's initial state, and return that HTML over HTTP. The browser will subsequently load all resources, just as usual. As soon as all JavaScript is ready the app will become interactive. Because all HTML is available directly, the app will be visible much quicker. In Lighthouse this is called "First Contentful Paint". As all data will be provided from the server-side, the rendering will happen much quicker, which will lead to a quicker Time to Interactive. This technique is called Server-side Rendering and is commonly abbreviated to SSR.
From Next.js 13 on, you can easily combine client-side and server-side rendering. Pages are server components by default, but you can simply turn them into client components by adding "use client"
to the top of a file.
It's recommended to fetch data inside server components, which always fetch data on the server. This gives you direct access to your backend data and is also secure by default, preventing sensitive environment variables from leaking to the client.
Static-site generation (SSG)
Static-site generation, abbreviated as SSG, is based on the same principle: pre-rendering an app outside of the browser. The main difference is that SSG renders all pages of an app and stores them as static files. Whereas SSR just pre-renders one page upon request. SSG is blazing-fast because of this, as all URLs are directly available to be presented to the user. Not just the one that's pre-rendered on the server as with SSR.
SSG must be coupled with "revalidation": the principle of renewing the data that was used when generating the application. Once a certain threshold has passed all data on the active page will be fetched once more. That way the Time to Interactive is very low for all pages, but outdated data will be updated quickly.
The SSG approach is highly effective for websites, webshops, and all other applications that offer content that's available and identical for a broad audience.
From Next.js 13 all fetched data is static by default, meaning it's rendered at build time. Next.js also automatically caches this data. Revalidation can be time-based, meaning the data will be revalidated at a timed interval (with time in seconds):
fetch('https://...', { next: { revalidate: 3600 } })
You can also revalidate on-demand, using revalidatePath
.
If you want to opt out of data caching, you can add cache: 'no-store
to fetch
requests or use revalidate: 0
.