Server-side rendering (SSR) vs static site generation (SSG) using AWS

Published on: Tue Dec 27 2022

Series

Content

Introduction

Every site has different needs, some are content heavy and some other ones are interaction heavy.

You may already guess one requires more Javascript than the other (hint: it’s the interaction heavy sites).

Most of the sites that you build or deal with are going to be blogs, marketing sites, et cetera. These sites are content heavy.

The two most common techinques for dealing with content heavy sites are Server-side rendering (SSR) and Static site generation (SSG).

If you’ve used Next.js or another frontend framework, you probably have come across or even used these techniques.

So, what’s the difference between the two ? and when should I use one over the other ?

Well... That’s what we will cover today!

(As a bonus, we’ll also cover how to achieve each of these techniques using services in AWS!)

Server-Side Rendering

When frontend frameworks like Angular and React started to become popular, everyone started using them.

There is only one problem with these frameworks, and that is SEO.

With single page applications (SPA), you send your initial HTML with your Javascript bundle on initial load.

Then, the page gets renderd on the client side using Javascript.

Search engines tends to have a difficult time indexing this type of application because it was built for indexing HTML.

So, many people started to come up with novel ways to generate the HTML to serve the request.

One of the techniques is by rendering the HTML on the server-side when a request is received, and that came to be known as Server-side rendering (SSR).

You can render your SPA on the server (just like you would on the browser), and serve that HTML when the page loads.

This way, you’d get best of both world, and search engines are happy because it knows what to do with a HTML page.

Pros:

  • Up-to-date data/content on the site (per request)

Cons:

  • Requires managing server or infrastructure
    • More moving parts and failures can occur
  • Some users may experience performance hit on round trip to server after CDN cache expiration

SSR Example using AWS

Here is example of using Server-Side rendering (SSR) with AWS.

SSR rendering with AWS
SSR rendering with AWS

There are two options:

  1. Render at the edge (using Lambda@Edge)

  2. Render at origin server (Lambda or ECS or any AWS compute)

For most use cases, you’d will use option #2 then cache the origin server results in a CDN like Cloudfront.

In some rare cases, you may choose to render content at an edge location if you want to improve performance.

Static Site Generation (SSG)

Static site generation (SSG) is similar to SSR in that it also generates the HTML output.

A good way to think about SSG is that you are rendering your pages ahead of time, then using those results to serve the requests.

The difference is when the HTML is rendered, and how frequently it will change it.

SSG generates the HTML output at build time, then the results don’t change until you rebuild it again.

You can probably see why this is good or bad.

If you have a site that just contains static data/content, and things don’t change that much, then SSG is a great fit for that site.

Pro:

  • The simplest approach
  • No server or infrastructure to manage
  • Can be cached in the CDN indefinitely (No performance hit when requests pages)

Cons:

  • Requires rebuild to update content (More suitable for sites that don’t change frequently)

SSG example with AWS

Here is example of using Static site generation (SSG) with AWS.

SSG rendering with AWS
SSG rendering with AWS

It’s quite basic, you essentially build your static site then upload it to S3.

Just doing this may be enough but you can also add on Amazon Cloudfront to distribute the content around the world if you have a global user base.

Bonus: Incremental Static Regeneration (ISR)

Now, you may be asking, what if I want something in between SSG and SSR ?

There is a technique for this, it’s called Incremental Static Regeneration, Next.js is the first framework I’ve seen that introduced this concept.

The idea is quite simple, you start off with your site generated via SSG.

Then, periodically, your server will re-generate the new HTML output.

The Pros and cons are same as SSR.

AWS Implementation

There are a few ways to implement this technique within AWS.

Solution #1

The simplest way is achieve this setup is to use SSR then cache the results with Cloudfront.

That way, you still get the periodic “regeneration” from SSR when the cache expires in Cloudfront.

In this case, the implementation is same as SSR (see above), then we just need to set the caching via HTTP cache headers or in Cloudfront.

Incremental static regeneration with SSR over time
Incremental static regeneration with SSR over time
⚠️ Note:

This is a variation on the classical ISR.

The downside with using SSR and CDN cache is that when regenerating some users may experience higher latency due to the round-trip to the server.

In most cases, these effects are neglible but for high traffic sites, every little friction matters.

Solution #2

Here is another implementation using AWS.

This probably fits with Next.js’s implementation of ISR better because the regeneration process happens in the background.

However, if you are self-hosting, this setup is a lot more complex. There is a lot of moving parts, and places to go wrong.

Incremental static regeneration with AWS solution #2
Incremental static regeneration with AWS solution #2

Here is the flow:

  1. Lambda@Edge receives a request from Cloudfront, and it adds a message to the queue

  2. Lamda@Edge will fulfill the request by fetching the stale results from S3

  3. The response is returned to the client

  4. The worker will pick up the message for re-generation

  5. The worker willl upload the results to S3 and perform invalidation on the Cloudfront CDN

In most cases, I recommend solution #1 over solution #2 for a simple setup but if you use a community package, you may not have a choice.

⚠️ Note:

With solution #2, the setup is more complex but you can have the benefit of performing the regeneration in the background.

That means the end-users won’t experience the increased latency, rather they’d just receive an outdated version of the data/content temporarily.

When to use SSG or SSR or ISR ?

It about striking a balance between simplicity and meeting needs of your site.

It’s a choice between:

  • Site Change Freqency - What is my requirement for how frequently I want the content/data on my site to change ?
  • Complexity - How simple can I make my infrastructure setup ?

Site Change Frequency

First, select how frequently the data/content on your site needs to change.

This typically depends on your content management source. This can be via a Content Management System (CMS) or user generated content (UGC).

How frequently does the site need to change ?
How frequently does the site need to change ?
⚠️ Note:

Static Site Generation (SSG) does not mean you can’t update the site easily.

It just means that you need to re-build it manually. It may be annoying but it is a viable solution if you want to keep things simple.

If you have a site that serves User Generated Content (UGC), which changes all the time, then SSG becomes more difficult.

Infrastructure Complexity

Ok, after you selected the solution based on how frequently you’d like the site to change.

Now comes the time to weigh the complexity of the setup. I think the goal here should be to make it as simple as possible.

It is a question of trading off based on what you need on your website.

Does this fit your needs right now ? Can you make it work with a simpler solution ?

Is not having up-to-date data/content a deal breaker for what you are building ?

Complexity comparison between SSG, SSR and ISR
Complexity comparison between SSG, SSR and ISR

Recommendation

Ok, so with all these information, I still don’t know which one to use.

I am going to assume that you will be self-hosting these solutions.

Here is what I recommend:

  1. SSG
  2. SSR
  3. ISR

Essentially, start with SSG, if that doesn’t work then move onto using SSR.

Finally, if you find that you don’t need to render every request, look into ISR to see if you can tweak the workloads.

Conclusion

And... there you have it.

A comparison between the three common techniques used to render websites:

  • Static Site Generation (SSG)
  • Server-Side Rendering (SSR)
  • Incremental Site Regeneration (ISR)

If you are using Vercel, all of these options are provided out of the box. Vercel does a lot of the heavy lifting for you.

If you do choose to go the self-hosting path, try to go for a managed or community package rather than build it from scratch.

Here are the options mentioned in their docs:

There is no hard-and-fast rules about which one you should use.

It’s always situational. It’s a fine balance between knowing the constraints of these techniques and the wants/needs of your website.

Most of the time the simplest solution is the best solution.

That’s all for now.

I hope you found this helpful or learn something new!

If you did, please do share this article with a friend or co-worker 🙏❤️ (Thanks!)


Enjoy the content ?

Then consider signing up to get notified when new content arrives!

Jerry Chang 2023. All rights reserved.