My Tech Blog

SEO in 2020 - SSR vs SPA

Shallow focus photo of desk globe

With major frameworks like React, Vue, Svelte and Angular, Single Page Applications (SPA) have never been more popular and are now an increasing part of the web. What are the SEO implications with a pure client side rendered website?

On the other side of the fence we have the traditional Server-Side Rendered (SSR) applications. Are they still the SEO kings in 2020, or have the times changed?

Background

Web development in ten years ago was a different story than today. Everything was server side rendered, and all the crawlers had an easy time to chew through content on the web. All they had to do was to request a documents HTML, and use that as the base for indexing.

The story is a bit different today, as many web sites serve an empty document in the HTML and then let Javascript take care of the rest. The crawlers then need to be able to execute Javascript in order to crawl and index the content.

Crawlers + Javascript = ?

As the web evolves, the crawlers need to keep up to date in order to index all the webpages out there on the web. An article from Moz from 2017 outlined the current state for how the different search engine crawlers handled javascript back then.

In 2020, we have to assume that they all are getting better at this, and that most of the SPA’s out there in the wild are getting indexed.

SPA vs SSR

So if the crawlers now can execute Javascript, why are not all new websites SPA’s? After all, they are easy to make, cheap to host and scales incredibly well with a global CDN. An SSR application requires a server to run, will therefore have higher hosting costs and is more tricky to scale, especially in a global context.

The downside of the SPA is that it initally serves an empty HTML document, which enforces a crawler to execute Javsacript before seeing any content. SSR gets a head start since all the important content is available in the first HTML. The question is though: how big is the head start? How much does it matter?

Experiment

Since we have no way of knowing how the different crawlers out there actually work under the hood, the only way to figure out which of the two methodologies for web sites are better, is to create an experiment.

The setup would be: two identical websites. Completely same content, same delivery network. Same domain authority. Everything would be 100% the same, except for the methodology. One would be SSR and the other would be SPA.

The website will consist of a frontpage that lists blogposts from an external source, Crystallize, and the individual blog posts.

Questions that need an answer

  1. Will both sites be indexed?
  2. Will all sub-pages be indexed?
  3. Which methodology will perform* best?

*Performance in this context translates to clicks and impressions for the blog post

Since this current blog post features some very popular search terms, like SEO, SSR and SPA, there are plenty of other webpages that will compete in the Search Engine Result Page (SERP), and provides a good way to measure the performance of both versions of the blog.

Hypothesis

Question 1: Will both sites be indexed? Yes, no doubt.

Question 2: Will all sub-pages be indexed? For SSR, yes. For the SPA, I think so. Since the crawler can execute JS, it should be able to pick up the link to the blogpost that is generated some time after the page has loaded

Question 3: Which methodology will perform best? My guess: SSR. I am uncertain though on how much better it will perform.

Making the websites

I am a huge fan of React, so for me it is only natural to use that for the view layer.

For the SSR website I chose NextJS as the SSR framework, since it at the moment the industry standard to make a SSR React application.

In order to be deliver the exact same content for both versions, I chose NextJS for the SPA version too, with one minor difference:

The SPA version does not download and execute the code required for each route until after the client has loaded an empty page. This mimics the behaviour of other pure SPA apps, where typically all routes are redirected to an index.html page, and the custom routes are resolved using Javascript.

Since both versions are using the same framework, we can be confident that they will deliver the same HTML shell and delivery speed, which ensures we can assume that the difference in SEO performance will only be due to the SSR / SPA strategy

Day 1 - Deployment

I hosted both versions on Vercel and aliased them to subdomains of a domain that I own:

Next, I registered both domains with Google Search Console, and queued them for indexing. Now all I can do is to play the waiting game, and check back in a few days to see if they show up in my KPI search term: “seo ssr spa”

Man sitting on gray rock while staring at white clouds

Day 2 - first results

Within the first 24 hours, the first results were in! On the SSR blog, the blog post was found and indexed by Google and received a place on the 3rd page in the index here in Norway. The SPA blog did not so good, and the blog post was not indexed.

In any case, question 1, will both sites be indexed, has been answered: yes they have.

I’ll give it some time, and check in later to see if Google has found the SPA blog post.

Week 1 status

After 1 week of being live, Google has now picked up the SPA blog post as well, so that answers question 2, Will all sub-pages be indexed, yes all sub pages (blog posts) have been indexed. The SPA version though took a bit longer to show up in Google Search Console. I don’t know exactly when it did, but it was at one day later than the SSR version.

Now, lets look at the performance for the blog post for each method

SSR
Total impressions: 16
Total clicks:: 6

SPA
Total impressions: 0
Total clicks: 0

Looks like the SSR version is in the lead. Let’s leave the websites in the wild for a few weeks before we check in on the results again!

Month 1 status

Since I wrote the week 1 status, the corona virus measures have been implemented in Norway, giving me the busiest three weeks of my life, and it has made me forget that this experiment existed.

I did remember eventually, and this is the accumulated clicks and impressions for the first month of the blog post (today is the 11th of May):

SSR
Total impressions: 89
Total clicks:: 12

SPA
Total impressions: 1
Total clicks: 0

In addition to this, the SSR blog is on the first page (number 5) in Google for the search term “seo ssr spa”. Meanwhile, the SPA version is nowhere to be found in Google (I stopped looking when I reached page 10).

Why the big difference?

So, there is a difference in performance here. A huge difference. Why is that?

Keeping in mind that the premise of this experiment was that we delivered the exact same HTML, we need to look elsewhere for answers. Not being an expert on SEO myself, I’ve pinned it down to one or more of the following things

Frontend performance, as measured by Google Lighthouse

Google is including Lighthouse audits when ranking on the search result pages, and performance is a very important metric. The better the performance score, the higher up in the search results you go. Simple as that.

Googlebots crawling strategy for SPAs

It could also well be that when the Googlebot crawls a web page, it first crawls the initial HTML, and then defers crawling the dynamic parts (scrolling, fetch etc) later.

Identical content on same top-level domain

It could be that we are tricked by some other Googlebot crawling strategy. They could see both sites as being equal in terms of content, and therefore discarding one of the websites from the search results.

Let’s check the performance for both strategies first.

SSR Lighthouse performance

Scoring of 95 in performance of SSR version

SPA Lighthouse performance

Scoring of 95 in performance of SP versionA

Kind of surprised to see identical scores, which means that Lighthouse values both versions to be equally fast. Performance can therefore not be the triggering factor.

This means that the reason for why the SSR blog performs so much better is due to unknowns inside Googlebot. Unknowns that are probably are going to change in the future. It is difficult to validate this, and I don’t think asking anyone on the crawling team about the internal dynamics of the Googlebot would yield any proper answers.

Conclusion

Wow, I have to say, I did not expect the numbers to be so clear on which approach would be the best one.

If SEO is a concern for your application, you still have to avoid an SPA and go either SSR or Static Site Generation (SSG), like Gatsby and Next.js if you are looking for React alternatives.

Source code of both websites are available here: https://github.com/hakonkrogh/seo-spa-vs-ssr