In this article, we’ll look into server-side rendering in detail. We’ll see how it works, what problems it solves, how it compares to client-side rendering, and what pros and cons it comes with.
An overview of single-page applications
The main goal of this architecture is to make web apps similar to native mobile and desktop applications in terms of interactivity. As SPAs only have a single HTML page that fetches data from the server asynchronously, users can see updates instantly, without having to wait for the whole page to refresh.
How does client-side rendering work?
Client-side rendering (CSR) is the default rendering method for single-page applications.
If you use client-side rendering, it’s the user’s browser that generates the entire app, including the user interface (UI), data, and functionality. No server is involved in the process, except to store the client-side code and data and transfer it to the browser.
As the following code example shows, in CSR apps, the HTML file only contains a blank
root (often also named
app) element and a
<div id="root"><!-- blank --></div>
Since the browser needs to download and run the whole application code before the content appears on the screen, the first page load is usually slow with client-side rendering (server-side rendering splits this process between the client and server).
As a result, users see a blank screen or loading spinner for a relatively long time. This leads to a poorer user experience and higher bounce rates (see Google’s discussion of how page load time impacts bounce rates).
Image credit: React PWA
Server-side rendering provides a solution to this problem.
What is server-side rendering (SSR)?
Here’s an example HTML file, containing a simple newsletter signup form, that the browser could receive with server-side rendering. All HTML elements inside the
root element were rendered on the server:
<input type="email" name="email"
placeholder="Enter your email" required>
Faster-loading static content versus less time between content visibility and interactivity is a trade-off between server-side and client-side rendering — but more on that later.
Steps in the server-side rendering process
In brief, server-side rendering consists of the following steps:
- Client’s HTTP request – When the user enters the URL into the browser’s address bar, it establishes an HTTP connection with the server, then sends the server a request for the HTML document.
- Data fetching – The server fetches any required data from the database or third-party APIs.
- Server’s HTTP response – The server sends this HTML document to the client.
- Page load and rendering– The client downloads the HTML file and displays the static components on the page.
Here’s how server-side rendering looks from the browser’s perspective. Note that the flowchart below starts with Step 4 when the browser gets the server’s response:
Image credit: React PWA
Server-side rendering frameworks and tools
- React uses the
ReactDomServerobject together with the
- Vue has a
createSSRApp()method and a corresponding server-side rendering API.
- Angular has its in-house server-side rendering tool called Angular Universal.
Pros of server-side rendering
Now, let’s look at the most important thing: the pros and cons of server-side rendering.
Note, however, that most of these advantages and disadvantages apply to different degrees. Their magnitude and impact will vary depending on the application structure, page weight, frequency of user interactions, and other variables.
To assess how much they apply to your app, you’ll need to measure your performance data in a reliable way and test different scenarios.
Better search engine indexability
As a result, client-side rendering is still considered risky from an SEO perspective. Put simply, if you want to rank high in search engines, server-side rendering is the better choice.
Faster initial page loads
As SSR apps pre-render HTML on the server, it takes less time for the browser to load content onto the screen.
However, note that while first-time visitors do experience faster initial page loads with server-side rendering, caching might change this result for returning users. If the frontend page doesn’t load any dynamic data from the server and all code is already cached, the browser only needs to render the page locally with client-side rendering.
Faster Largest Contentful Paint (LCP)
LCP is a time-based value measured in seconds. A lower value means a better LCP score. As the largest content element (either an image or text block) is part of the static content your server pre-renders, SSR will display it faster on the screen.
Lower Cumulative Layout Shift (CLS)
Cumulative Layout Shift is another Core Web Vitals score tracked by Google. It measures the amount of unexpected change in the dimension and position of your content elements after the first page render.
With server-side rendering, the browser doesn’t have to go over the rendering process step by step, which typically results in fewer random layout shifts and, therefore, better CLS scores.
Fewer issues with social media indexing
Better for accessibility
As the server sends pre-rendered content to the browser, SSR apps are more suitable for people who use older devices with less powerful CPUs.
Cons of server-side rendering
Despite its numerous advantages, there are still some cases when SSR might not be worth the effort. Here are the most important drawbacks of server-side rendering.
SSR increases complexity, which may or may not be worth it for you. You’ll have to write universal code that runs both on the server and client, take care of more complicated dependency management and caching, set up and maintain a server environment, find developers with the proper skillset, and more.
Obviously, this more complex architecture will be more expensive, harder to maintain and debug, and more prone to errors.
Potentially higher First Input Delay (FID)
First Input Delay is the third metric of Google’s Core Web Vitals. It’s also the one where server-side rendering might lead to web performance issues. FID is a time-based value measured in milliseconds. It shows how long it takes for the browser to respond to the user’s first interaction.
With server-side rendering, the browser displays static content faster (which leads to a better LCP), but it still needs time to hydrate the application. As a result, the app looks ready for interaction while the code is still being processed in the background. If the user tries to interact with the app during this period of time, there will be a delay in the browser’s response.
The extent of the first input delay depends on many things, including your app’s complexity, whether there are many interactive elements, the page weight, and others. For many SSR apps, first input delay won’t be an issue.
However, if you experience higher FID, you still don’t have to give up on server-side rendering, as there are ways to mitigate it.
For example, your UI can indicate to users that the app is not yet ready for input (e.g. you can hide or disable the buttons) so that they won't try to interact with it too early and, therefore, produce a high FID score. Alternatively, you can eliminate long-running blocking tasks by splitting up rendering into smaller chunks.
Less efficient caching
With server-side rendering, the page HTML is different for each page, so it’s harder to cache this on a CDN. Users who load a page that hasn’t been cached on the CDN will experience a longer page load time.
There are several third-party libraries and tools that are not compatible with server-side rendering.
However, on the backend, we use the standard TypeScript compiler rather than Webpack, so we had to switch from SCSS includes to Emotion, a CSS-in-JS library, to render these components on the server.
Even though nowadays compatibility issues are less of a problem than used to be, you still need to choose your dependencies carefully if you want to use server-side rendering.
As client-side apps don’t need a server, you can deploy them to a free or cheap static storage service such as Netlifly or Amazon S3. However, you’ll need to pay for a server or at least a “serverless” backend to deploy an SSR application, which means higher running costs.
Larger HTML size
SSR apps come with a larger HTML size because of the embedded hydration state.
This is not really an argument against SSR, just something to keep in mind as a potential risk if it’s implemented poorly. You can test your app for HTML bloat and other issues with our free HTML size analyzer tool.
Summary: Is server-side rendering better?
All in all, server-side rendering has a positive effect on page load times, SEO, social media support, and accessibility. On the other hand, client-side rendering can be cheaper, easier to build and maintain, and better for First Input Delay.
You don’t necessarily have to choose between these two options, though. There are hybrid solutions, too, which might work better for your application.
For example, you can use server-side rendering for pages important for SEO and client-side rendering for highly interactive pages. You can also set up dynamic rendering on the server to detect the client and serve a static version of your app to search engine crawlers.
With DebugBear, you can gain insight into your detailed web performance data, compare it against your competitors’ results, and run synthetic tests from multiple locations around the world — all from a single user-friendly dashboard that you can try for free.