Wednesday, August 30, 2023

To SSR, or not to SSR

Rendering Pattern

 views

Cover photo for To SSR, or not to SSR

TL;DR

There are two values added by using Server-Side Rendering (SSR).

  1. Search Engine Optimization (SEO)
  2. To a lesser degree, better performance, specifically in terms of First Contentful Paint (FCP)

If SEO is not a concern in your use case, e.g., you are building an internal app, then sticking to Client-Side Rendering (CSR) will be a better option.

What are some disadvantages of using SSR instead of CSR?

In short, it increases the project's complexity and, hence cost.

Codes run on multiple environments

In a CSR app, there is only one environment to worry about, the browser. So, it is clear that some Node.js packages that are meant to be used on a server, e.g., fs will not work here. However, for an SSR project, there are multiple environments to worry about. At the minimum, the browser and the server. Codes may be run on either of the environments and sometimes, both.

Let's consider a simple example, a component that displays the current URL of the website.

component.tsx
const Component: FC = () => (
  <div>{window.location.href}</div>
);

This works perfectly fine in CSR, but not so much in SSR. This will be the error you will face if you try to do so in an SSR app.

ReferenceError: window is not defined

The reason is this component will first be run on the server side to "server render" it. And since window is a browser API, the server will not have access to it. So, in the world of SSR, we need to handle the case where window is not defined.

component.tsx
const Component: FC = () => (
  <div>{typeof window !== "undefined" && window.location.href}</div>
);

This might become natural as the development team gets familiar with how SSR works, but this is just an extra thing to worry about that simply doesn't exist in the world of CSR. Not to mention server side nowadays can have multiple environments like serverless or the edge. Or the newly introduced React Server Component that completely changes how SSR traditionally works. So, a real-life scenario can get way more complicated than this.

You need a compatible backend for an SSR app to work

In a CSR app, the built project is just several static assets that can be served by the simplest web server. An SSR app, on the other hand, as its name suggests, needs a backend service to support (a part of) its functionality.

Let's take Next.js, a popular React SSR meta-framework as an example. Next.js offers a built-in image optimization feature that allows developers to serve images of the right format in the right size to the users. The catch is that this feature requires a backend service for it to work.

This feature is not unique on its own. Many web hosting service providers also offer a similar feature set with a price tag on it. So, to promote their service, some of these service providers do not or only provide partial support to Next.js's built-in image optimization feature. And obviously, Vercel, the company behind Next.js and a web hosting service provider, supports the built-in feature out of the box.

This introduces a dilemma. Should we

  1. Deploy the app to a 3rd party web hosting service provider and subscribe to their image optimization service, or
  2. Deploy to Vercel or even
  3. Forget about image optimization and pick whatever service provider you like.

Conclusion

Although many web apps nowadays make use of SSR to power their sites, SSR should not be the default choice for web development. The KISS principle applies perfectly in this scenario. Don't use SSR simply because everyone is using it. If you don't benefit from the values brought by SSR, then there is no reason to suffer the costs it brings.

Written By

Matthew Kwong

Matthew Kwong

Senior Web Engineer @ Viu