4 ms·
> If your app is architected to have any rendering operation take long enough that it's perceptible to the user, STOP DOING THAT THING DURING RENDERING. At my
by _bxg1 7y ago
> If your app is architected to have any rendering operation take long enough that it's perceptible to the user, STOP DOING THAT THING DURING RENDERING.
At my workplace we frequently encounter cases where the rendering itself - just the evaluation of the pure React functions - takes hundreds of milliseconds, if not several seconds. This is after memoizing every part of it that can be memoized, after profiling it for places where work can be shaved off, etc. Sometimes there really is just that much rendering, and unlike other types of computation, today's React gives you no options for putting that in a worker or breaking it up. Tabs' single threads mean you can't even scroll in the interim. Concurrent Mode is the only hope we have of solving that case, other than avoiding it with paging, which is what we currently do.
- paulddraper 7y ago> React gives you no options for putting that in a worker or breaking it up. Isn't that React Fiber? [1] "Fiber breaks down animation into segments that can be spread out over multiple frames." How does that differ from React Concurrent? Are they compatible? [1] https://en.wikipedia.org/wiki/React_Fiber https://en.wikipedia.org/wiki/React_Fiber
- _bxg1 7y agoSo, I'm not sure exactly how Fiber works, but given the context and what I've read/watched, here's my guess: Confusingly, there are multiple tiers of "updates" happening in a React app. One is when your render functions are called to recompute their React element trees. Work can be avoided here via shouldComponentUpdate(), etc. Once React has this internal data structure, it uses it to do another level of updates to the actual DOM. This part is totally black-boxed from the application code, because React has all the information it needs internally to avoid unnecessary updates at this level. I think, maybe, that Fiber is specifically focused on this latter stage. Concurrent Mode would then be the stage 1 equivalent of what Fiber does in stage 2. This would be why it has an effect on how application code can actually be written, where Fiber didn't really.
- acemarke 7y ago"Fiber" was the rewrite of React's internal render logic (primarily how it processes the component tree), and was released in 16.0. It's named after the data structure that is used to track individual pieces of work (roughly on a per-component basis). Fiber does specifically divide the overall update process into two general phases. "Render phase" involves walking the component tree, asking components what the desired UI should look like, and calculating the diff and necessary changes based on the previous requested output. Once that's been calculated, it is applied all at once in the "commit phase". Concurrent Mode is, loosely, additional modifications to that rendering logic to enable pausing partway through the "render phase" process, tracking one or more in-progress versions of render passes, prioritizing them based on the source of the requested update (user input vs network request, etc), and recalculating in-progress renders if another higher-priority render was pushed to the front and committed to the DOM first.
- AgentME 7y agoReact Fiber is the internal name of some of React's systems that were necessary in order to support the Concurrent Mode feature.
- davedx 7y agoFiber is the underlying engine used by concurrent mode. I really recommend browsing the react reconciler source code. I don't immediately understand most of it, but you can get the gist of it.
- hakanito 7y agoSince you mention scrolling, it sounds like you are rendering a lot of off-screen content... Have you looked into solutions like react-virtualized? It can definitely speed up the experience
- _bxg1 7y agoI haven't; the amount of magic going on makes me a little wary, but it does seem like it could be a good solution. Maybe I'll give it a try.
- davedx 7y agoIt looks like React concurrent mode also deprioritizes the rendering of off-screen content for you. (I've been browsing the react reconciler source this morning...)
- Geee 7y agoYou can make it happen by rendering all components first as 'null' or placeholder <div> and pushing them on a queue. Then loop the queue with requestAnimationFrame() and set a batch of components visible for every frame. You can give each component a cost so that each batch will fit in a frame. It's basically a simple component that you can wrap around components that you wish to render in the queue. I have been using a solution like this for a long time in production and it works great. You can combine this with virtualization if you have lots of non-visible components.
- _bxg1 7y agoWe've done a bit of that, but at that point you're just rolling your own, highly-stateful version of Concurrent Mode.