The future of React / ReactJS — React Fiber
If you’re in involved in front end development, you’re used to the changing tides that occur ever so occasionally. If you’re involved in any development that is front end, you’re often warned to stay away, not because it’s tough but because of how exhaustive it is to learn and keep up with the frequency of all the frameworks that pop up, and become a new “fad”, dare I say ever, so often.
In the midst of all of this, there are two kings that prevail, at least in terms of downloads & contributions & industrial adaptation, this may fail in other contexts, these are Angular and React. We won’t go into Angular in depth, but know that Angular is Google’s brain child and was one of the reasons for changing web and introducing the Front End and Back End independence model, as to back end templating. Angular is scheduled to release V4, not 3 very soon, this skip is intentional and to do with their internal packages versioning — Angular Router was in V3 when the rest of the Ang suite was in v2, and to avoid this future confusion, Ang router will continue it’s natural increment to V4 and the rest of Angular will follow.
Sorry for that, had to give credit and context to Angular, it is an amazing tool. But to the topic of this blog — React. In relay of what was mentioned at the start, let frameworks come and go, React (and Angular) are here to stay, why, well mainly because React is great internally, not just a buzzword, it solves an actual problem, makes development componentized and sensible, its ridiculously intelligent and fast, but more importantly it’s back by one of the biggest companies in the world, Facebook.
So React moved from its 0.12,0.13 etc versions straight to 15.x.x on April 7, 2016. But what about it in 2017, is React a fad that is going to die ? I mean it has lived past the age of most frameworks, 4 whole years since its 2013 release :o. Well it’s not going, its here to stay, for a while at least-ensue the topic of discussion React Fiber, React’s future.
The project was highly experimental, and has been in the works for almost two years, but is conceptualising to something more tangible as we speak. No this doesn’t mean we have to relearn React, it’s just a complete internal re-write of React, mainly focused around updating and further optimising the famous reconciliation (diffing) algorithm, the same algorithm made famous via React’s Virtual DOM.
Why rewrite though ? It comes around the context of scheduling, in computational terms, when should a task be performed and how to prioritise tasks, in Reacts context reconciliation, re-rendering via setState/prop changes as examples.
On a side note, lets talk about two software approaches. The push and the pull approach.
In a push based approach, you as an application decide when to do a process
In a pull based approach, the library is allowed to be smart enough and make those process decisions for us. In the current version of React, the library decides when to follow through with a process.
There, however, is no scheduling involved in React, i.e if a user triggers an event that causes external library state change, you know MobX, redux, “insert buzzword”, which then causes a component to re-render, or if there is an internal re-render via the setState method, the entire component and its subjective subtree re-render synchronously, i.e priority isn’t given over another process. More context, what would you reckon be more important, a click that causes a small UI change, or an animation that is running at the same time at 60fps? In my opinion, A drop in frame-rate for animations is always destined for poor user experience as to a small delay in the change of a value due to a user interaction. Without scheduling all updates are characterised with the same priority, which can sometimes lead to poor UX.
Another cool example would be deprioritizing rendering of items in long lists that haven’t yet appeared on the the users active screen. If a component that isn’t on the screen is updated, is it even important to stop all other processes to re-render it ?
In reference to scheduling is concurrency, i.e concurrency in a single thread as to multi-thread (parallelism). A call to re-render a parent would cons-equate to that parent’s entire subtree to re-render synchronously without any interference.
How do we fix this, well common sense would suggest to interrupt low priority work, do the suddenly high priority work that just showed up, finish that — and then go back to the low priority task.
Alright — quick quiz, could you tell me what a React component is, it its raw essence, minus all the JSX and ES6 stuff ?
If you guessed, a function, you’re right. A react component is nothing but a function of data, and in that terminology, ‘rendering’ basically means calling a function. Now with that being said, how do we stop a sub-tree from re-rendering, i.e how to we interrupt a function call ?
If you guessed generators, you actually are correct, but in the implementation of React Fibre not exactly, however the concept of generators can loosely apply.
Side note again, have you ever used stashing in your git flow ? When you want to temporarily cache your disk changes , do something else, and bring those disk changes back ? i.e stashing. If you have existing changes, and you want to pull code down, you’ll most likely go through an error that’ll suggest deleting or stashing changes, if you stash, you store this changes in a stash “imaginary array”, then you complete your git pull, and then you “pop” the stash, similar to an array and your stashed changes are brought back to disk.
React Fibre does something similar, but more similar to how call stack tracing happens in Chrome’s debugger tools. In the words of Andrew Clark (Redux co-creator), React Fibre is a virtual stack frame, with React Fibre being a reimplementation of a stack frame specialised for React components. Each fibre can be thought of as a virtual stack frame where information from the frame is preserved in memory on the heap, and because info is saved on the heap, you can control and play with the data structures and process the relevant information as needed.
It is also to be noted that each stack frame has a number signifying priority relative o the other stack frames. It also contains a field that memoizes input invoking a re-render only if input has changed (kinda like shouldComponentUpdate, or when we extend to PureComponent) , and of course keys for optimal reconciliation (diffing)
Footnote — This article has been heavily inspired and influenced by Andrew Clarks talk in 2016 on React Fibre. He joined the facebook team recently and is helping build the future of React with Dan Abramov.
He continuously keeps us, the rest of the world, on React Fibre’s architecture and progression. Follow & Star https://github.com/acdlite/react-fiber-architecture
PS, i know i’ve called in Fibre in the blog and not Fiber, blame autocorrect.
www.Five2One.com.au is a software consultancy based in Sydney, we’ve built products for start ups and large tech firms. We’ve worked with global startups and multi-national companies ranging from the Insurance, Aviation, Law, Car Manufacturing all the way to the Betting industry. Get in touch and lets make software development collaborative, sensible and great!