React just reinvented the wheel again in 2018! And how they did it!
Dan Abramov who is working on React at Facebook just released a video where he is presenting about the new stuff that they are working on at Facebook. The first thing is the stuff related to the whole React Fiber rewrite, and he showed how that allowed asynchronies updates to the DOM, something not possible before. His example was really great as he showed how it got progressively slower as more elements were created; it simply takes more cpu for more elements and the browser stops responding when you render it all at once.
The solution is to do it asynchronously, where you split up the work into smaller chunks and allow the browser to handle browser events like typing. That is really hard to do because sometimes splitting up work is not possible if you have to do it halfway through a render, but react solved that 👏
The second part that he showed was about only rendering components when the data is ready. That is the always hard problem and something Dan Abramov library is used a lot to, Redux, have one place where you store the data and calculate immediate steps to show, as for an example loading screens. Typically you emit at least two events, LOAD_DATA to tell the application to go into loading state and LOAD_SUCCESS to tell the application it has the data and can now show the screen. As you can imagine with a growing application you begin to have a lot of these events that all loads applications. Dan shows a perfect example of an application that loads external data and the key point is that the app should still be responsive during the render. The user should never experience a application that is not reacting or slow.
He shows in the video how he makes the application wait until the data is loaded simply by wrapping the call in a createFetcher
and no state library. It simply stops execution where he calls the function from and even though it does not have the data is does not fail with a “ReferenceError: “x” is not defined”, it simply does not execute from there. I was really curios how he did it and the genius solution is using the functionality throw
!?! Something that you would normally use to throw new Error('something wrong')
is he using to simply throw a promise that when it resolves, React will know that it can try to render that specific component again! That is genius!
He could also have used async/await,
but the problem is that the application would not know how to proceed as it simply halts the process of that specific function and it would delay the render. To archive speed the render
function has to be synchronous for it to be fast at rendering and making a diff between two virtual dom would not be possible, as those promises could potentially never resolve in time or ever. By throwing the promise it can still be synchronous and super quick and the render function does not need to be changed to a Promise
and that is a relief, as it would have made it more complicated!
This is the reason why you should use React! VirtualDOM can be pretty simple to make as other libraries have shown, but doing this kind of optimisations are really hard but the improvements to the user experience is worth it as it is 10x better!
See the video here:
https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html