Asynchronous React Server Side Rendering

Mark Uretsky
2 min readJan 17, 2017

--

Drastically improve your RenderToString & renderToStaticMarkup performance.

I guess you’re probably having a react SSR performance issues and that’s why you’re here, for the time being RenderToString is a synchronous and it sucks for performance. It blocks the node.js CPU and it can’t handle any other requests until it’s finished. Usually (20–300ms) depends on what kind of components you’re trying to render.

Current Options (But there is a but)

You can use https://github.com/electrode-io/electrode-react-ssr-caching to cache your react component which is nice it gives you 70% rendering performance boost read more https://medium.com/walmartlabs/using-electrode-to-improve-react-server-side-render-performance-by-up-to-70-e43f9494eb8b

But be careful caching can be hard to get right, I mean it comes with risk that something might not work as you expect so you need to be careful in what are you caching, What I decided to do is to cache only stateless component that are not dynamic like footer, logo etc. And it works really well so give it a try if you need a performance boost in rendering speed.

The Real Antidote to The Performance Problem

So after implementing electrode react ssr caching and reducing the render time for component to 20ms-50ms. My servers were still taking a beating CPU usage over 50% (80–100% before electrode), increasing the servers number didn’t make a drastic improvement going from 4 to 20 servers and I was still getting problems from the CPU jumping all over the place 30–80%.

So what is the real problem with renderToString? Lets see if it takes 200ms to render your component and it’s blocking the CPU you can support just about 5 users a second (WOOT?!) just because the render call is synchronous it’s BLOCKING the rest of the app and it can’t render the same component or make any api calls etc, unless it’s finished.

The solution is to make the whole 200ms non blocking It doesn’t really matter that much if the user has to wait 20–200ms to render the component but when it’s synchronous it’s blocking other users by 400ms-800ms and getting worse the more traffic you get, so the real problem is much much worse it makes SSR unusable in the real world if it’s synchronous.

There are some ways you can fix that:

  1. you can wait for react team to ship the new react fiber core which will make it possible to create an asynchronous renderToString
  2. you can move your server side component rendering to a different web server (microservices), AWS Lambada etc.
  3. execute the render function in a node child process which will make it asynchronous (child_process.fork())

I’ve decided on using the third approach for the time being, AWS Lambada could be cool for a server less SSR but it will take extra configuration and maintenance I don’t want to maintain for the moment.

Hope you find this helpful

UPDATE (26.11): Guys just use React 16, It’s really good for SSR I don’t have any issues anymore :)

--

--