Also.... 20ms with caching the pages in Redis? That sounds really, really slow. There's definitely something else going on.
Heres' a comment from reddit I would like to share
Cloudflare only caches about 30% of your requests for a major site. If you're small, they'll get everything, but every CDN has limits on how much of your data they keep on edge. As a free CDN, Cloudflare has pretty stringent limits. Also there's the issue of cache invalidation, which is a lot easier if the cache is something that you control totally yourself. Additionally, a local cache can help you save partial content, which is the next step in any 'make this site fast' strategy.
Hope it helps.
Which, given I'm seeing much much less for a rather complex React app... makes me suspicious that something else is going on with their codebase.
I'm seeing maybe 150ms as the upper 95 percentile but median would be 30-60ms and my app isn't exactly small or simple.
BTW have you ever worked with SSR and React ? 150ms is pretty standard time it takes to render a page with SSR. And as mentioned in the post, the 150ms is what we are getting. This is purely dependent on your project. For example, a simple "hello world" page might take a lot less than a full page with lots of components.
And 20ms is the total response time for the page. Redis takes just 2-3ms of it.
If you're properly using Redis, then the total response time should be 2-3ms, or at least very close to that.
> BTW have you ever worked with SSR and React
I haven't - I was hoping the article would shed light on it. The top comment seems to have some great suggestions. There's probably a lot of optimizations one can make at the React/Redux level.
> After peeling through the React codebase we discovered React’s mountComponent function. This is where the HTML markup is generated for a component. We knew that if we could intercept React's instantiateReactComponent module by using a require() hook we could avoid the need to fork React and inject our optimization. We keep a Least-Recently-Used (LRU) cache that stores the markup of rendered components (replacing the data-reactid appropriately).
> We also implemented an enhancement that will templatize the cached rendered markup to allow for more dynamic props. Dynamic props are replaced with template delimiters (i.e. ${ prop_name }) during the react component rendering cycle. The template is them compiled, cached, executed and the markup is handed back to React. For subsequent requests the component's render(..) call is short-circuited with an execution of the cached compiled template.
Except you don't have to peel through their code base or intercept any calls, they expose a clean interface for this: https://github.com/facebook/react-devtools
You can capture it like this:
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = function(obj) {
// obj.Mount
}
Which is how we're doing SSR at https://www.prerender.cloud/ for compatibility across React versions.So SSR using just renderToString doesn't respect that hook.
I wonder when using shell scripts and/or Makefiles instead of Webpack/Browserify/Gulp/Bower/NPM/whatever for building will become popular again.
All the tutorials seem to focus on using it for c++ projects with all of their complexities when it's really simple for a a typical java or c# project.
> Whenever you deploy, new chunk hash for js and css files gets generated. This means if you’re storing the whole HTML string in the cache, it’ll become invalid with the deployment. Hence, whenever you deploy, the redis db needs to be flushed completely.
These arguments sound like over-engineered "solutions" by somebody who did not do their homework. To speed up your SSR, render components, not the _whole_ page. Vast majority of your page is going to remain constant: the head, navigation, footer. Rendering these components in partials will save you the Redis store by a very, _very_ large margin. Once they start caching hundreds of thousands of HTMLs, the Redis server will start swapping the content from memory to the disk. There, you just defied the whole point of using Redis.
Also, your users are _still_ going to see the 810ms latency the first time they access your service. How often do you think they'll be reloading right after the page is loaded? And once the cache is invalidated -- which I suppose would happen frequently -- the _visible_ latency is still high.
That is totally wrong. Rendering components again and again is not performant at all. "Rendering components, storing them somewhere and finally when user requests, stitch them and give it to the user." Is that your solution ? That would be even more expensive than normal rendering.
> your users are _still_ going to see the 810ms latency the first time they access your service
That is not true too. Only one user will see the 810ms latency. All the users, when access this page, will get sub 20ms response time. Have you ever worked with servers/caching and know how they work ?
String concatenation/substitution is more expensive than DOM parsing?
> Only one user will see the 810ms latency.
If your whole content is cacheable, then a CDN will be far more useful and have way less than 20ms response time. 20ms is not fast. Selectively invalidating CDN content as new data is available is much more performant.
> Have you ever worked with servers/caching
Yes.
> know how they work
Yes, still learning though.
They're often high latency (for a service - 180+ms) but are also high availability.
Slap a CDN in front (like Fastly) and get in the 10s of ms response time if possible.
that's really really really bad for generating a html (and even sending it to the user).
I can achieve the whole damn thing in 20ms or less.
> The average response time fell to 20 ms !
yep in java/go/whatever you don't need the cache, with it your avg response would drop even further!
You can also invest in a CDN. Now we have a React.js SSR with 0ms server response time! :)
[0]: https://github.com/aickin/react-dom-stream [1]: https://www.youtube.com/watch?v=PnpfGy7q96U [2]: https://github.com/facebook/react/issues/6420
As far as I know, as long as the content is embedded in JSON/JS when the page loads, it's fine to then "render" it with JavaScript. It's 2016 and Google started crawling JS websites a while ago.
However, if you fetch it with AJAX after the page loads, Google won't see it because it doesn't necessarily follow AJAX calls nor wait around for them to return in 810ms. They'll most likely only render the bundled content.
You can use the "fetch as Google" tool in Google Webmaster Tools to try this out for yourself.
Umm .. nice work ? I guess ..
My browser would thank you