Live data from Hacker News

The Performance Cost of Server Side Rendered React on Node.js

malloc.fi

71–80 of 134 posts

Re: The Performance Cost of Server Side Rendered React on Node.js

#71

Earlier quoted context omitted.

It's a real issue, my startup's react SSR times are ~5 seconds of blocking the node thread on my $40 droplet. It's about 50% react. Our pages are way more sophisticated than your average page with like a query and a form, though. There are many ways to make faster though, one of which is to simply configure your CDN properly.

50% on plain rendering is very unexpected. Complex apps tend to have bottlenecks on IO/data fetching more than just plain rendering. I would love an article detailing your experience and measurements.

our renders are compute heavy because it is so dynamic (most of today's apps aren't). Think of it this way. Virtual DOM is like a spreadsheet. You only want to recompute the stuff downstream of what's changed. That's basically what React's render-tree pruning is all about. But there are a couple problems.

First, naive server rendered React isn't diffing anything at all, it recomputes the whole virtual dom from scratch every time. So there isn't any render-tree pruning since we're not doing a diff. That's what the walmart-labs patches help with, since obviously a lot of SSR'ed components aren't changing between SSRs, that can be reused, and we can be fast again.

Second, React.js views are more than just banging html together, it also has to call a bunch of functions as part of that process. For example client side sorting, or map/reduce/filter. So if those functions are expensive, your views are slow, even if the html itself isn't all that complex.

Third, since much of our "view rendering" cost is actually computation not directly related to making html, React can't reuse pieces of those computations anyway. You'd need to code your "math" in terms of React components even though there's no html associated with them.

Fourth, if your dataflows are dynamic enough, like a spreadsheet, even if React actually could optimize those computations (which it cant), it wouldn't even be helpful, because while Views are trees, many computations are not. For example, in a spreadsheet: Edit cell C7, quick what is the tree of computations you can skip? The question doesn't even make sense, because spreadsheets aren't trees. Spreadsheets do complicated graph dependency tracking, with cycle analysis and all that, in order to make this fast. React doesn't do that.

As an example of how dynamic Hyperfiddle is, go to http://dustingetzcom2.hyperfiddle.net/ and in the top toolbar click "data" and then click "dev". Dustingetzcom2 is not coded in javascript, its coded in data, and you edit the data live in the dev pane, and the right things update live as you make changes. That's why the render computation is so expensive.

Re: The Performance Cost of Server Side Rendered React on Node.js

#72
post #10

Earlier quoted context omitted.

Correct, except that initial app load time for un-cookied users with cold browser caches is a critical metric, since it largely determines whether they'll keep using your app. Fortunately, those are the scenarios where server-side caching can have a decent benefit, since you're essentially rendering the same view to all such users.

Modern JS frameworks try to solve this problem by inlining critical CSS and JS into the head for anything above the fold, and loading the rest dynamically.

Which frameworks do this?

Re: The Performance Cost of Server Side Rendered React on Node.js

#73

If you're on the fence about server-side rendering being needed for your webapp don't do it! As a team of two with one engineer, I decided YAGNI and instead focused on the responsiveness of the React and Redux-based web application. It is very snappy to load and our (paying) customers are happy. You might not need SSR. I don't. I expect there will be more work to optimize it and eventually it'll be obviously a good i…

It's the other way around: you might not (in fact, probably do not) need React.

Start with server-side rendering, and move to React if your application's dynamism demands it. Most applications don't. It's painful to see so many websites building huge, slow, JS-rendered monsters for one or two dynamic elements per page. Unless you are Facebook (and have your JS cached within one hop of every internet POP in the world), server-side rendering is going to yield performance wins for nearly all visitors.

Re: The Performance Cost of Server Side Rendered React on Node.js

#74

Earlier quoted context omitted.

50% on plain rendering is very unexpected. Complex apps tend to have bottlenecks on IO/data fetching more than just plain rendering. I would love an article detailing your experience and measurements.

our renders are compute heavy because it is so dynamic (most of today's apps aren't). Think of it this way. Virtual DOM is like a spreadsheet. You only want to recompute the stuff downstream of what's changed. That's basically what React's render-tree pruning is all about. But there are a couple problems. First, naive server rendered React isn't diffing anything at all, it recomputes the whole virtual dom from scratc…

That... is not very dynamic.

I'm sorry, I'm looking at your example link and you should be getting rendering times in the sub 40ms range. Unless that's not a representative example of course.

Nothing in there seems particularly un-reusable.

Re: The Performance Cost of Server Side Rendered React on Node.js

#75

Note that React doesn't do streaming HTML in the traditional sense. You can't send out initial HTML while you wait on an API response, for example. Instead only the serializer is streaming. Your app renders to a VNode synchronously and then the serializer traverses the VNode, synchronously, and streams the strings out as it goes. This is why streaming is only a little bit better in these numbers. If/when React gets r…

React 16 supports streaming! https://reactjs.org/blog/2017/09/26/react-v16.0.html#better-...

Re: The Performance Cost of Server Side Rendered React on Node.js

#76

Note that React doesn't do streaming HTML in the traditional sense. You can't send out initial HTML while you wait on an API response, for example. Instead only the serializer is streaming. Your app renders to a VNode synchronously and then the serializer traverses the VNode, synchronously, and streams the strings out as it goes. This is why streaming is only a little bit better in these numbers. If/when React gets r…

React 16 supports streaming! https://reactjs.org/blog/2017/09/26/react-v16.0.html#better-...

Oh sorry I should read better! Sorry

Re: The Performance Cost of Server Side Rendered React on Node.js

#77
These results are not surprising to me but it's great that they were published because people have been very quick to jump on the hype bandwagon for these kinds of projects.

I think that the idea of the isomorphic JavaScript app never actually worked in practice. MeteorJS already had a really good go at it.

Sharing JavaScript modules between the client and the server is great but when you start to pretend that the backend and the frontend are the same environment, you're bound to run into all sorts of problems and create inefficiencies.

The kind of performance penalty incurred by server-rendered React is bound to make your system vulnerable to DoS attacks or at best make it unnecessarily expensive to operate.

When programming abstractions shift too far away from the reality of the underlying architecture, you will start paying dearly and the cost won't be worth it in the long run.

In my opinion, the client-server divide is a fundamental aspect of multiuser applications and no amount of abstraction can make it go away.

Re: The Performance Cost of Server Side Rendered React on Node.js

#79
For this reason, we don't use SSR for pages that change often, and turn it off completely for authenticated users. Some performance analysis showed it was actually slower in the average case than shipping the JS and having the client render it themselves, especially with a hot cache.

This still provides what we wanted anyway; the ability for pages to easily be viewable without JS and easily indexed by search engines.

Re: The Performance Cost of Server Side Rendered React on Node.js

#80
post #73

If you're on the fence about server-side rendering being needed for your webapp don't do it! As a team of two with one engineer, I decided YAGNI and instead focused on the responsiveness of the React and Redux-based web application. It is very snappy to load and our (paying) customers are happy. You might not need SSR. I don't. I expect there will be more work to optimize it and eventually it'll be obviously a good i…

It's the other way around: you might not (in fact, probably do not) need React. Start with server-side rendering, and move to React if your application's dynamism demands it. Most applications don't. It's painful to see so many websites building huge, slow, JS-rendered monsters for one or two dynamic elements per page. Unless you are Facebook (and have your JS cached within one hop of every internet POP in the world)…

Well that is a whole other debate. The best thing about React is common patterns. Second best is the availability of components. I've worked with JavaScript for a long time -- the Backbone.js days were painful. It was easy to accidentally leak event binds, code yourself into a corner, etc. The jQuery days were almost better in some ways but still had some real pain points.

You missed that I'm working on SaaS and a web application. Client-side state is important -- each of my customers can load up most of their state to client-side and the performance is great. This is the whole point of client-side apps. Get rid of all that round trip latency sending HTML to the client of every click. Get rid of your complex server-side framework. Client-side is simpler if you learn and embrace it (and don't need server-side rendering). It's also much easier to have a consistent UX with client-side state.

So use what is appropriate for you use case. For mine, that is 100% client-side no doubt. You can't beat the performance for an application.

Post reply on HN