Static Site Generation vs Server-side Rendering vs Client-side Rendering
TL;DR
What does "rendering" mean?
Rendering = generating HTML
3 primary rendering modes
A rendering mode defines the stage at which your page’s user-facing HTML is generated.
- Static Site Generation (SSG): render at build time.
- Server-side Rendering (SSR): render at run time, on server-side.
- Client-side Rendering (CSR): render at run time, on client-side (browsers).
Many popular frameworks (e.g. Next.js, Gasby.js) now support multiple rendering options.
Static Site Generation (SSG)
The entire site is pre-rendered into HTML, CSS, and JavaScript at build time, which then get served as static assets to the browser. The content is ready to go before the visitor even visits the site.
Pros:
- No running servers or databases.
- Can be easily deployed to cloud storages (AWS S3, GCP Cloud Storage, etc).
- Content gets to the user faster.
- Secure, no binaries to be hacked.
- Can be cached by the CDN.
- Good for SEO: the content can be crawled even for crawlers that don’t execute JavaScript code.
Cons:
- Individual HTML files must be generated for every possible URL.
- Cannot handle dynamic routes; infeasible if you don’t know all the URLs at the build time
- Long time to build and deploy if your site has a large number of unique pages.
When to use:
- For web pages that don’t change depending on the user: home pages, landing pages, technical documentation, blog, etc.
Server-side Rendering (SSR)
Generates the full HTML for a page on server-side in response to each request and send the rendered HTML to the client. (React: renderToString()
)
Pros:
- Can handle dynamic routes on the fly.
- Rendered page will always be up-to-date.
- Avoids additional round-trips for data fetching and templating on the client.
- Avoid sending lots of JavaScript to the client, which helps achieve a fast Time to Interactive (TTI).
Cons:
- Generating pages on the server takes time, which can often result in a slower Time to First Byte (TTFB).
When to use:
- For pages / sections with user-specific (personalized), authentication-gated information, like profile pages or personalized dashboards.
- For user-generated content, like comments, that a user would expect to be live immediately after posting.
Client-side Rendering (CSR)
Render on client-side (browser) at run time; all logic, data fetching, templating and routing are handled on the client rather than the server. Example: create-react-app.
Pros:
- May update part of the content without full page re-render.
- May be easier and cheaper to host.
Cons:
- The amount of JavaScript required tends to grow as an application grows.
- Could be slow to start.
- Bad for SEO.
When to use:
- Single Page App.
- If your application is only available to authenticated users.
Mixed Options
Deferred Static Generation (DSG)
An option in between SSG and SSR: statically generate critical pages at build time, and defer non-critical page generation until a user requests it.
Pros: reduce build and deploy time, while keeping the critical pages readily available.
Use case: larger sites that have lots of infrequently accessed content, like old blog posts.
Static Rendering vs Prerendering
- Static Rendering: pages are interactive without the need to execute much client-side JS
- Prerendering: improves the First Paint or First Contentful Paint of a Single Page Application that must be booted on the client in order for pages to be truly interactive.
To test:
- disable JavaScript and load the created web pages. For statically rendered pages, most of the functionality will still exist without JavaScript enabled. For prerendered pages, there may still be some basic functionality like links, but most of the page will be inert.
- slow your network down using Chrome DevTools, and observe how much JavaScript has been downloaded before a page becomes interactive. Prerendering generally requires more JavaScript to get interactive, and that JavaScript tends to be more complex than the Progressive Enhancement approach used by static rendering.
Rehydration
Combining SSR and CSR via rehydration.
Rehydration = client-side JavaScript converts a static HTML web page, delivered either through static hosting or server-side rendering, into a dynamic web page by attaching event handlers to the HTML elements.
This allows for a fast "first contentful paint" (when useful data is first displayed to the user), but there is a period of time afterward where the page appears to be fully loaded and interactive, but is not until the client-side JavaScript is executed and event handlers have been attached.