Enhancing SSR with React 18 : A deep dive into server side rendering optimisation

Server side rendering (SSR) is a popular technique for improving the performance and SEO of web applications by rendering HTML on the server and sending it to the client. However, the traditional approach to SSR has significant drawbacks, especially as applications grow in complexity. 

Is your SSR approach optimal? 

Traditionally, SSR processes the entire HTML response synchronously. This process can result in longer server response times, particularly for larger applications, which can negatively impact the user experience. The key problems with traditional SSR today include: 

  • It fetches everything before displaying anything – the server needs to gather all the data before it can render and send HTML, leading to delays. 
  • It loads everything before hydration. All components must be loaded onto the client before the application starts to hydrate (make the HTML interactive) 
  • It hydrates everything before interaction. Users can’t interact with the page until the entire hydration process is complete, meaning longer wait times.

App demonstration with traditional SSR approach

The demo application uses React and NodeJS server for server-side rendering, and consists of the following components:  

  1. Cart 
  2. Header 
  3. Footer 
  4. Sidebar 

We assume that the cart component took two seconds for data fetching on the server side:

Traditional SSR metrics: 

  1. FCP (first contentful paint) – 2.2 seconds 
  2. LCP (largest contentful paint) – 2.2 seconds 
  3. Blank screen time frame: the application shows a blank screen until the HTML is fully received from the server 
  4. TTFB (time to first byte) – 2.01 seconds

These metrics indicate a poor user experience, with prolonged blank screens and slow interactions.

Two major SSR features unlocked by Suspense 

The new SSR foundation introduces several important changes that offer a better user experience, including: 

Streaming HTML 

Streaming HTML on the server involves sending HTML content to the client  in chunks as it is generated, rather than waiting for the entire page to be rendered before it is sent. This allows users to see and interact with the initial content faster, improving perceived performance and reducing TTFB. 

SSR with streaming can significantly enhance the user experience, especially when using large or complex applications. HTML streaming offers benefits such as: 

  • Faster TTFB with immediate start of content download 
  • Faster FCB since visible content appears sooner, reducing perceived load time 

Selective hydration on the client 

Selective hydration, introduced in React 18, optimises client-side performance by allowing critical parts of the application to become interactive, faster. One benefit of this change is an improved user experience – critical components become interactive sooner, leading to a smoother, faster interaction 

Improvements in React 18 for SSR 

Key improvements that we see in React 18 include: 

  • Suspense and Lazy on the server side 
  • Streaming HTML with Suspense boundaries. By using the React server API’s ‘rendertopipeablestream’, HTML is streamed in chunks with Suspense boundaries, enhancing performance and rendering speed. 

Metrics for demo application with Suspense and HTML streaming

  1. FCP (first contentful paint) – 0.3 seconds
  2. LCP (largest contentful paint) – 0.5 seconds 
  3. Progressive rendering – the application progressively renders using HTML streaming from the server 
  4. TTFB (time to first byte) – 30.32ms 

SSR demonstration with selective hydration  

Below is a video demonstration showing how the application remains interactive even when the Car component is not streamed, or the JavaScript fully downloaded. This illustrated the effectiveness of selective hydration in enhancing the user experience by prioritising the interactivity of critical parts of the application. 

React 18 solves these problems:

  • You no longer need to wait for all data to load on the server before sending HTML 
  • You no longer have to wait for all JavaScript to load to start hydrating
  • You no longer have to wait for all the components to hydrate before interacting with the page

React 18 improves SSR application performance 

By leveraging React 18’s Suspense, React.Lazy and HTML streaming, we can significantly enhance the performance of SSR applications. These improvements mean faster initial loads, quicker interactions and a much improved user experience. 

Traditional SSR methods are becoming increasingly outpaced by the new technologies and methods like those introduced in React 18, which set new standards for web application performance and user satisfaction. 

This demo application on Github shows the benefits of SSR with Suspense and HTML streaming.