You Don’t Need SSR (frameworks)

Introduction

My team and I recently worked on optimizing the performance of one of our SaaS applications, in order to reduce infrastructure costs, and improve overall user experience by cutting down loading and rendering times as much as possible. We explored many options and tested different frameworks. Server-Side Rendering was one of the techniques we especially focused on. Here is our feedback regarding this solution. As the title suggests, this article is quite one-sided, however I tried to rely on factual data as far as possible, so that it is not just a debate of beliefs.

What is Server-Side Rendering?

Nowadays, when we talk about web apps, it usually means an application written in JavaScript, using a popular frontend framework out there (VueJS, React, Angular, Svelte to mention the most famous ones). In such case, everything is generated on the client side (i.e. in the browser), once all the essential assets have been loaded. Most of the time, the web page returned by the server looks like:

  • Computation is now mostly done in browser, freeing a lot of load from back-end, reducing their usage costs and increasing the amount of traffic they can handle.
  • It is possible to create fully interactive pages, with a much more deep user experience than with static pages while avoiding successive reloading.
  • As pages are not sent once generated, search engines and crawlers won’t index anything valuable (although this statement may be obsolete now, as all modern crawlers are able to execute JavaScript and wait for the page to be rendered before indexing its content).
  • Performance/UX: the fact that pages are not sent back ready to be displayed to end user makes it potentially longer to load. Especially when network connection is bad, or device computation resource is limited. We’ll come back to that point later.

Challenges brought by SSR

Theoretically, it sounds like a great idea. But in practice, while trying to implement this system, you will find yourself facing a bunch of new challenges, that can require entire teams for days, and can cause many headaches to solve. In his article, stereobooster makes a pretty accurate list of those concerns you will have to deal with. To sum up, you will have to ensure that the following is also working seamlessly on back-end:

  • Dynamic data fetching from an API or any web service before rendering
  • Using a front-end router, or internationalization (i18n) utilities
  • Using HMR for development
  • Lazy loading components
  • Using a state manager like redux or diox

SEO

As I previously mentioned, without SSR, your website’s indexing won’t be impacted on Google or Bing. But it will most likely be on other less advanced crawlers. Before trying to fix that point, the most important question you should answer first is: do you really need SEO?

Performance & User Experience

This part is a bit more complex to determine, as it varies a lot from device to device, and depends on both network’s quality and performance. Firebase team made a very interesting series of videos speaking about how essential SSR is and how it dramatically improves your app’s performance and reactivity. But if we think about it from another angle, what do we learn? When it comes to improving pages loading times, only 3 KPIs matter. FP, or First Paint, this is the time it takes before the browser actually displays something to the user. FCP, or First Contentful Paint, is the delay after which the page AND meaningful data are display to the user. And finally, TTFI, or Time To First Interaction, is the time from which user is able to interact with the page (e.g. clicking buttons, navigating, …).

Web app with SSR
Web app without SSR
  • With SSR, page takes much more time to load because API calls are performed on back-end, before sending any response to the client. During that time, end-user is just waiting in front of an white screen. However, once everything is loaded, useful content is displayed sooner than without SSR. Regarding TTFI, as all assets are required and DOM must be hydrated, user sees a complete page, but he cannot interact with it for 2.5 seconds. It makes the app feel cumbersome, laggy, and can generate frictions.
  • Without SSR, page is loaded way faster (twice, actually), but is only displaying a loader / splash screen / whatever is in the HTML page at first, for 2.5s until the JavaScript has been completely loaded and interpreted. At that moment, user can really interact with the UI, but no interesting content is displayed. Meaningful content appears 2.5 seconds later than with SSR. Nonetheless it gives you a window to let your user know the app is still waiting for the payload, by displaying relevant UI elements.

Costs & Complexity

Besides the two main concerns we previously discussed, there is another one that developers don’t really talk when promoting SSR: the costs that inevitably come with increased complexity.

  • Enabling SSR requires to rewrite a large part of your app so it is 100% isomorphic (although you never completely achieve that). It takes a huge amount of time, that you could have spent improving other aspects of the app or focusing on other ways to increase performance.
  • You will definitely need a more powerful and complex infrastructure, as making an app work on back-end has many implications in terms of security and features.
  • Your servers will be able to handle much less traffic than before (because of the computational resource it takes to render pages), increasing your costs.

Conclusion — About simplicity

I personally like very much the saying YAGNI, or “You Ain’t Going to Need It”, because it makes totally sense, especially in software engineering. Developers love finding new problems, coding awesome stuff and framework that beautifully solve them, for the sake of technological achievement itself, more than the benefits it actually brings to end-user. I believe that SSR is one of them. It makes you loose focus on what really matters, your users. It’s another technical challenge that brings infinite discussions and costs so much time for such a small ROI.

  • NextJS, for the React ecosystem
  • NuxtJS, for the VueJS community

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store