React Server
react-server.io
react-server.io
We've tried to keep data store selection out of React Server core. There are so many good options in the React ecosystem that picking one seems limiting.
The data bindings that the framework cares about are at the http request level. We have a wrapper around `superagent` that manages transfer of response data from the server to the browser. So, when the client controller wakes up in the browser and tries to make the same requests that the server just made while _it_ was rendering the page, the data is already present and the requests are short-circuited.
FWIW, I've found the isomorphic render examples within the Megaboilerplate examples for React [0] to be instructive.
;)
I'm coming up on a decade in web application development and I feel like this is one of the most critical skills. It also took me an embarrassingly long time to develop. I think engineering, in allowing transparency downward into each level of the "stack", engenders the opposite in it's practitioners.
1. Google for a blog comparing them, and eliminate any candidates with major red flags
2. Go with the one that has the most stars on it's github repo.
I don't find JS has a "first mover lock-in" problem. If anything, it has the opposite...
What can ya do? This is where we find ourselves today. It's a mess. But what if I told you there was another way...?
num dependencies (shallow, deep)
total size of node_modules
installed size (correct use of npmignore etc)
code quality (McCabe, jslint, jshint)
typescript/flow/ jsdoc string types etc
test coverage
frequency of releases
documentation coverage
documentation text analysis: pretentiousness, overly laconic, bro speak
has a F-ing README so we could at least have some idea what the hell it is
number of blog and link references
number of authors
reputation of authors based on their other packages
open/closed issues
Make the stats available so others can build indices and ranking algorithms based on these.That ecosystem can be impressive but it's madness to keep up with it.
Two weeks for setting up boilerplate? Is that normal for react?
I imagine your parent didn't literally spend two whole weeks just on that, but I might be wrong if he's very thorough.
In any case, the configuration of all the parts of the "canonical react stack" (let's not forget, react could be used without all of this junk too) is a pain, but I hope once you get the hang of it you can just reuse and don't think about it so much.
(For example, I've seen some that implement some custom Redux middleware simply so that there's a conceptual reference right in the boilerplate as to how one would be done).
Are you thinking of getting into it? I heavily advise checking React out. I think it's fantastic!
You'll get a Hello World up in 30 seconds, upgrades are painless and you'll get the same rendering speed as with React thanks to the glimmer engine.
And thanks to the standardisation, all Ember apps have the same code and logical structure, which makes it easier to share code, and for developers to dive in new projects.
We need better docs in general. Contributions welcome! :D
As a dev and a creative person, I understand the desire to get something out there. But documentation and tutorials aren't just something that's nice to have. They are your marketing tool, your adoption driver, and the way to create educated advocates for your project. They are as valuable to your project's success as a splashy "getting started" web site is.
The proof (and splash) is in the pudding here. Kudos to dev team that built this.
If the response "Contributions welcome" is generic, it's because the complaint is as well.
Oh, hey didn't mean to sound flippant there! We're definitely planning to make tutorials, and we're constantly trying to improve our docs. I guess my point is we want this to happen faster, but we're still a pretty small project with a small team of core contributors. So we're thrilled when we're able to bring in new contributors to help out!
"No documentation survives its first encounter with a real newcomer."
I hope it didn't seem like I was accusing you of negligence – the docs you have are an awesome start, and I fully appreciate the difficulty of the problem. Best of luck with things going forward, looks like a really neat project.
So how exactly does the server perform that same fetch when attempting to hydrate the full page without actually making an HTTP request against itself?
There's no data caching across pages. On first page load the responses from data requests for that page are transferred to the browser and rehydrated. For a client-side transition to another page there are two options: Fetch the data from the server as a bundle (this just works... one of the cooler features of React Server, I think) or make the individual requests via xhr from the browser. Both have their place.
There's some more discussion of this here: https://react-server.io/docs/guides/client-transitions
There doesn't appear to be special handling for this use case. However, they use SuperAgent (https://github.com/visionmedia/superagent) for http requests and I expect implementing the behavior that you're describing is relatively easy with their plugin system. Specifically I'd bet that plugins previously designed for testing could be used to accomplish your goal (superagent-mock or superagent-mocker).
In React, people typically use the ExecutionEnvironment module [2] for this:
if (ExecutionEnvironment.canUseDOM) {
// make client side request
} else {
// make direct db request
}
...but you could also just do some simpler check, like see if `window` exists, or make up your own `IS_SERVER` global, etc.Next you'll wonder: won't that still ship the server-side code to the browser, even if it's not run, and pull in any server-only modules you're importing, e.g. database access stuff? No: you'd fix this with (for example) webpack's `DefinePlugin` [3], telling it that `ExecutionEnvironment.canUseDOM` should always be `true` wherever it occurs in your client-side JS bundle, and dead code elimination will then rip out those server-only `else` branches before that code gets shipped to the browser.
Or a similar setup, like wwalser hinted at: write 2 versions of your 'request' module: one for the client, and one for the server. Tell webpack it should point to the client-side one when you generate your client JS bundle. People use webpack because it lets you do all kinds of overrides like this.
[1]: I work at Formidable, we do a ton of React for big companies.
[2]: https://github.com/JedWatson/exenv
[3]: https://webpack.github.io/docs/list-of-plugins.html#definepl...
Imagine writing tests with mocked requests. Now apply that same logic to all calls to fetch() on the server. Does that make sense?
So to the front end when fetch() is called, it actually makes the request. On the server, when fetch() is called it hits a mock plugin which fetches "mocked" data which is just fetching data from whatever local store you normally would on your backend be it a JSON blob on the file system, a database or an in memory cache.
editing to say that @exogen gave what may be a better explanation below: https://news.ycombinator.com/item?id=12273029
That's what I'm apparently failing to describe how to accomplish :).
My team owns one special-snowflake API in React-Server. We want the API to be reachable from the client via HTTP, but also want to execute the code directly during server-side rendering, with no HTTP call. It's your exact use-case.
In order to do that, we
1. Detect if the API is invoked server-side.
2. Tell Superagent* to tell the client "hey, if you want data for $API_URL, don't make an HTTP request; the response will come inline in the page's HTML response.
3. Invoke the API code directly.
4. When the API response is ready, serialize it, and tell Superagent to pass it to the client.
We don't do this kind of thing frequently, so we haven't built any graceful tooling for it.
* I _think_ this is Superagent: https://visionmedia.github.io/superagent/https://visionmedia.... Somehow, we use it in a way that notifies the client of what HTTP requests the server is performing on its behalf; not sure if that's stock Superagent or if we added some magic to it.
https://github.com/erikras/react-redux-universal-hot-example
How does this compare to that?
https://github.com/erikras/react-redux-universal-hot-example...
That said, react-server attempts to solve the problem in more of a framework fashion. I hope to look further into it.
After blocking 2 iframes with adblocker I could finally inspect what was going on :)
Anyway, I can definitely feel that is fast and seamless and worth to give a deeper look! In the meantime, prefetching all the content in docs or source views upon load generates quite a few requests and might explain your scaling issues. Would you mind sharing statistics for number of users and hardware behind ?
Anyway, the errors in the console aren't impacting the behavior of the site (the badge is falling back to polling to get updates, for instance). They are ugly, though, and will be gone in a future deployment.
Amazon announced the Application Load Balancer today which supports Websockets:
https://aws.amazon.com/blogs/aws/new-aws-application-load-ba...
Thanks for the heads up!
The data hydration, incremental HTML delivery and incremental code loading are really, really important for creating web apps that aren't load time hogs. Great to see that they were unopinionated about data fetching, too. That's one of the things that has made it difficult to drop Relay into existing applications.
Is this used in production? Are there any performance numbers that you can share.
"We’ve been using it here at Redfin in production for over a year and it serves the three highest traffic pages on the site. We’re serving 1 billion requests a month from our React Server instance; hundreds of requests per second during peak hours."
Instead of the render() method in React to output JSX, it appears that ReactServer uses getElements() for a similar purpose. So the entire model and object lifecycle is probably different as well?
The server streams each section's static HTML to the client as soon as it's ready, and after all prior sections are streamed.
The server also streams the async data to the browser. This avoids the latency of the client downloading some HTML, then downloading some JS, then making the requisite API calls for the page's data. (Think of it as a hacky version of HTTP Server Push.)
On the client-side, React and your JS are downloaded, React will recycle as much of the static DOM as possible (writing isomorphic JS isn't always easy), then take over and do its thing.
Where are these waiting sections? On the browser client or the server?
Is the React code that is to be rendered on the browser served up automatically by ReactServer?
I'm sure it's a wonderful framework, but a diagram is really needed to understand any of this.
The server tells the client what requests it's making on the client's behalf.
If the client's JS tries to make a request for a URL that's already in-progress, the client's React-Server code will skip the request and return a promise of the server's streamed response instead.
If the client's JS tries to make a request for something, and the server IS NOT already handling it, then the client will send out an HTTP request, and React-Server will step out of the way.
This might be the evolution of it, where the page routing is residing on client with server side state ?
Would appreciate feedback!
- The server can render the full page in html for the client, which means the website is viewable even without js (or before js has loaded, for example on slow network)
- The server can preload all data the client needs. The webapp might need to fetch data from 3 API endpoints. Having a server do this and pass the results to the client on load is much more efficient. If the client (browser) loads it, the following happens: html loaded -> js loaded -> start calling APIs. If the server does it, the client instantly has access to this data.
Rendering all the html can be a bit heavy on a weak server though, but you get the advantage that you quickly notice bottlenecks in your rendering. You can also implement some caching on your server to make it faster.
What usually happens in a react app is that the server delivers static content (html, js, css). When everything is loaded, react starts working on the browser and renders / fetches data.
If the server that delivers the html doesn't just deliver a static page, but actually fetches data and renders it first, the browser can instantly display the data and react is smart enough to know that it doesn't even need to do a new render, because the components are already rendered to html.
Cool, I never knew that.
As I understand, Pages are composed of Components, Components provide HTML sections. HTML sections are loaded incrementally.
But if you want it all in one place (reduced complexity and overhead), React Server looks pretty promising.
My evaluation is that react-server looks promising for prototyping and first versions of an application where being monolith is a reasonable approach. Hypernova seems like a good fit for organizations that are already building microservices and want to eek some additional performance out of the initial render of their SPAs.
For some reason this week I stumbled over many great React.js articles, so I started a collection here http://deepreact.com mostly to save&share things with friends, since a lot of us are getting deeper into React now.
We wanted the project website to serve as a demonstration as well as a source for documentation.
When you land on the site the first page is rendered by the server. Then the client controller wakes up and subsequent page views ask the server for data, but render in the browser. That's what we mean by "seamless transitions".
Will have to think about a better tag line... Thanks!
https://elements.polymer-project.org/elements/neon-animation...
I think your value proposition is something like: "Renders on the server or the client - whichever's fastest for that request"
I'd assume when he says "first page" he means any first page but generally from there the rest becomes dynamic react. Depending on how you load your data it should be much quicker to render entirely in the browser once the page has loaded.
The user-agent string could be used to decide which approach to use.
Thx for Redfin btw!
You want to server-side render React apps so that while all that happens, the app already works.
Just curious, if it's been successfully running in production for over a year, why is it only being used to serve three pages?
(Also, just to be clear, we treat all home details pages as a single logical page.)
Click on Get Started and no seamless transition, but rather a very abrupt page load.
"Well... we made it through the first hour or so of HN traffic on a single t2.medium instance in ec2 before we started seeing errors. We're now on three m4.larges with good head room. Not too bad, I think?
We meant to get cloud front set up before we got this sort of traffic, but glad to be surprised with an early bump. :)"
This is me saying this: I think we are thoroughly over-provisioned now for the load we are seeing, but we wanted to avoid any more hiccups while you all are trying to check it out.
I don't have a good feel for what HN traffic is like. From one post (https://news.ycombinator.com/item?id=8107658), it seems like a few thousand hits/hour over a fraction of a day, but (1) there's a lot of variation, (2) it doesn't tell you the peak rate
It would be nice to have another day of similarly high traffic to verify it, but I think most of our scaling up yesterday was to handle the WebSocket issue.