I like it and I very much like react.js, but there's a very bad flash of no content followed by quick iterative loading, a frequent problem with pure JavaScript applications. I bet your react component's render is calling multiple times for each new item you load, and that seems unnecessary. I realize react says you shouldn't worry about this, but there I doubt that multiple renders are going to be faster than a single render as with each render the CSS has to be recalculated by the browser. When the browser parses pure HTML and renders Hacker News proper, it's not that slow, you do not see each item load.
I agree (although this doesn't really have anything to do with React itself—the app just shouldn't render page until items are loaded—are they fetched in parallel?)
The issue is more likely the timing of the data arrival than just because render is being called multiple times. It would be pretty easy to fix.
I actually have been really pleased with the combination of a few related react packages (mostly react-async) put together in this sort of quickstart repo:
It's extremely easy to write a primarily client side app that still prefetches its data and renders the initial HTML on the server (which would completely eliminate the issue here).
I like the idea of prefetching data if it is done apart from serving the HTTP response, blocking an HTTP response for an API call seems problematic. Hacker News doesn't update that frequently so it could be scheduled independently of a page load, every so many seconds or invalidate a cache and just make one out of every n requests load slow.
Firebase has a node.js SDK so it's possible to do that pre-fetching server side too.
With the right set of abstractions, you can use an API to get data from the client side, and a direct local database lookup (or cache here, or whatever) on the server. This is, of course, a bit more difficult than the simplest version, and probably isn't worth it until you're further along.
+1 for using the Firebase API for realtime notifications rather than rolling your own API polling.
Moreover, their API is consistent between the browser and Node.js clients, so almost all the application code can be shared. Just inject the appropriate client and away you go.
Uhm... no, I don't think react-async is a good way to manage data flow in React applications. I wrote it when I started to work with React but now I consider React Async an anti-pattern.
Interesting. I actually ended up not using react-async, because we were trying to manage all the data at the top level, but I'm not entirely convinced that's the way to go (at least not for every app).
I just started playing around with react pretty recently, and it definitely seems like people's opinions about how to structure things have shifted pretty quickly.
Have you considered marking it as deprecated on the repo's readme? I'd be interested in reading your thought processes between writing react-async and decided it was an anti-pattern.
I've added a paragraph to the README. Basically UI lifecycle and data flow should be decoupled. React component's state (which is used by React Async to store data) is for UI state and not for data.
I don't think React render calls is the issue. I think it's just a visual UI issue that could be largely solved with some sort of clear loading state (like a spinner).
I've tried something on the landing page now - it fakes the <ol>-numbered items based on the page number while it's waiting for the list of top story ids to load, and displays animated spinners while loading individual items.
No, this isn't a React render issue (and React render in general doesn't have this issue. Put a `key` on your component and everything will work correctly). If the item isn't changed then its DOM representation isn't touched either, so neither is the CSS recalculated.
He can freely render as many times as he wants (a dozen function calls won't be your bottleneck); I'd even argue it _could_ be nicer that everything's rendered gradually this way, but that's just an aesthetic choice.
This was just the most simple way to get started. I was surprised the result wasn't _completely_ terrible :)
Every individual item uses a ReactFireMixin method to register its own Firebase reference, binding the incoming data as an object in its state, so they pop in as the websocket receives data, then auto-update every time new data arrives.
Auto-updating has a lot of potential but also a few usability concerns.
You'll find on other auto-updating comment systems that "x new comments" is introduced so that you don't lose the spot you were viewing and you have the choice of seeing the new comments or not.
Animations and color can be used to show the movement, appearance, and disappearance of items. This would be great for seeing how votes and positions of items are changing.
I implemented "x new comments" for Hacker New as a userscript [1]. Thinking of doing something similar by having new comments add themselves as "new" if you're already on a page and caching the max comment id seen in localStorage for when you revisit.
This API really needs something sitting with the websocket always open on the backend to do some caching, particularly for comment counts.
If top stories were being cached and data passed top-down rather than fetched individually as with this hack, you could even reuse the same React components to pre-render on the server.
21 comments
[ 3.0 ms ] story [ 54.4 ms ] threadI actually have been really pleased with the combination of a few related react packages (mostly react-async) put together in this sort of quickstart repo:
https://github.com/andreypopp/react-quickstart
It's extremely easy to write a primarily client side app that still prefetches its data and renders the initial HTML on the server (which would completely eliminate the issue here).
Firebase has a node.js SDK so it's possible to do that pre-fetching server side too.
Moreover, their API is consistent between the browser and Node.js clients, so almost all the application code can be shared. Just inject the appropriate client and away you go.
I just started playing around with react pretty recently, and it definitely seems like people's opinions about how to structure things have shifted pretty quickly.
This stuff is too fun :)
He can freely render as many times as he wants (a dozen function calls won't be your bottleneck); I'd even argue it _could_ be nicer that everything's rendered gradually this way, but that's just an aesthetic choice.
Every individual item uses a ReactFireMixin method to register its own Firebase reference, binding the incoming data as an object in its state, so they pop in as the websocket receives data, then auto-update every time new data arrives.
You'll find on other auto-updating comment systems that "x new comments" is introduced so that you don't lose the spot you were viewing and you have the choice of seeing the new comments or not.
Animations and color can be used to show the movement, appearance, and disappearance of items. This would be great for seeing how votes and positions of items are changing.
I implemented "x new comments" for Hacker New as a userscript [1]. Thinking of doing something similar by having new comments add themselves as "new" if you're already on a page and caching the max comment id seen in localStorage for when you revisit.
This API really needs something sitting with the websocket always open on the backend to do some caching, particularly for comment counts.
If top stories were being cached and data passed top-down rather than fetched individually as with this hack, you could even reuse the same React components to pre-render on the server.
[1] https://twitter.com/jbscript/status/462657449497874432/photo...