Dan Abramov: Beyond React 16 | JSConf Iceland

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Thanks JavaScript Jesus

πŸ‘οΈŽ︎ 29 πŸ‘€οΈŽ︎ u/beeskneecaps πŸ“…οΈŽ︎ Aug 30 2018 πŸ—«︎ replies

pardon the shameless plug but since this talk I have been collecting everything that everyone has been doing that is downstream from the talk: https://github.com/sw-yx/fresh-async-react/

There's talks, demos, libraries, code, twitter chats, all in there. This thing is big and the conversation is happening all over the place. Just trying to make a resource for myself and hopefully it benefits others too.

Edit: questions welcome btw. just realized i spent the past 6 months of my life collecting this lol

πŸ‘οΈŽ︎ 52 πŸ‘€οΈŽ︎ u/swyx πŸ“…οΈŽ︎ Aug 30 2018 πŸ—«︎ replies

BTW this is from April (not a new video)

πŸ‘οΈŽ︎ 8 πŸ‘€οΈŽ︎ u/archivedsofa πŸ“…οΈŽ︎ Aug 30 2018 πŸ—«︎ replies

I love this guy

πŸ‘οΈŽ︎ 11 πŸ‘€οΈŽ︎ u/[deleted] πŸ“…οΈŽ︎ Aug 30 2018 πŸ—«︎ replies

His clock demo was something else.

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/skidmark_zuckerberg πŸ“…οΈŽ︎ Aug 31 2018 πŸ—«︎ replies

Will async rendering allow the calculations to be potentially pushed off to a web worker thereby freeing up resources on the main thread?

πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/freebit πŸ“…οΈŽ︎ Aug 30 2018 πŸ—«︎ replies

Good stuff. Related question: what benefit does Facebook get for developing something like React? Is it monetary or only for reputation type of stuff?

πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/[deleted] πŸ“…οΈŽ︎ Aug 30 2018 πŸ—«︎ replies

What I want to know is: when is it out?

πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/BUTTminer πŸ“…οΈŽ︎ Sep 06 2018 πŸ—«︎ replies
Captions
all right hi my name is Dan and I work at Facebook on the react team and in this talk I want to talk about the future of react and originally when I planned this talk I thought that I would talk about react 16o release and then the upcoming react 16 free release which finally fixes the contacts API and then talk a little bit at the end about the future of react but I was playing with some features that my teammates have been building like future features some of them we've talked before some of them we've never even talked before and I realized that I actually want to dedicate my whole talk to these new features that aren't available yet but I find them pretty fascinating and I hope you like them too so disclaimer I'm going to show the demos this is a very kind of demo oriented talk the things that I'm showing are not production already yet the exact api's will change don't fixate on them too much but I want to emphasize that this this is a real builds of react so there's enough fake journals these are using actual actual react code and I want to start with a question and the question is as library developers we need to think about our immediate users the developers who are building apps and also the users of our users that is the actual people parties in those apps and so at Facebook our scale is pretty global so we need to consider all kinds of connections and all kinds of devices such as you know high powered CPUs like on a laptop or low powered CPU such as on the mobile device and either fast or slow connections and we need to think about how can we as library developers empower the application developers to give the best user experience regardless of the device or the network and is there anything that we are can do better to enable them so when we think about those issues we tend to group them into two different areas the issues related to the computing power and the differences in the computing power and the different the issues are related to the differences in network speed and I'm going to refer to this as CPU and IO and in the context of react when we think of the CPU work you usually think about creating the Dom nodes creating components rendering them updating them calculating the updates and so on so things that are tend to be synchronous and when we think about the i/o work in the context of react we should think about the data fashion and the code splitting so is there something that we I could do better in those areas I'm going to start with the CPU area and I have a demo as I said this is a demo oriented talk so this is my demo if maybe it doesn't look like a real I have that T built but at least it's pretty beautiful and it's graphic so it's easier to see from the audience but what I have here is I have a tax box I can type into the text box hello yes come and I have a bunch of charts and every time I type the charts update and I made it so that the longer I type the more complicated the charts become so this lets me show that no matter how fast the implementation of component is eventually if the component tree is deep enough and there are enough Dom nodes there is enough computation is going to slow down and I don't mean to nitpick us on a specific like chart example the you can imagine that instead of a chart there could be any kind of react component tree so the main point is just that it's a heavy tree with a lot of dumb notes a lot of components and it updates every time I type and so already with this level of complexity when I type I experience color and I'm the one who experiences it you're probably maybe you don't see it so I build a small clock so the clock shows the how how the screen updates so when the when the crate sorry when the clock is green it means that the last frames are were drawn pretty near to each other so it feels responsive but if you see when I type I can see yellow and even red this means that it takes a lot of time between different frames so the user experience suffers and eventually no matter usually no matter what kind of app you're building eventually you're bumping into this problem where no particular component is slow but you just have so many features and such deepness then that you have this problem so the typical solution to this is to debounce the input so instead of updating the updating the output immediately as a type I can just wait until the type and finishes and then do a single update so I can type the the input is completely responsive but then the user experience suffers in the sense that if my computer is actually powerful enough so like I will remove some characters to make the the the complexity smaller I still have to wait until to finish typing to see the results so this program doesn't really adapt to the performance of the of my computer and to the complexity of the team and this is even more pronounced if I enable the CPU throttling so CPU throttling is a way to emulate performance of a mobile device of a less powered device so I will slow down the CPU by 4 times and now you can see that even so a type which is called Iceland and even though you waited a little bit it still froze the underlying it's just that the update is big and it's synchronous so as soon as the react starts rendering it cannot stop well what if there was a way to make updates asynchronous so that reactive starts rendering something but then healed back to the browser and if there is a higher priority event like an input the browser could handle that first and not started a thread so I will disable the throttle thing for now let's see how it normally behaves in asynchronous mode so what you can see here is that when the input is short and it doesn't there is not a lot of computation in a base almost synchronously so it feels like as if it were synchronous but if I type more what happens is that instead of hanging the thread the thread says responds if you can see that it's most agreeing but instead we actress updates the chart it's left less often and the elect behind my input a little bit but in many cases this actually doesn't matter and it's a completely fine compromise from the UI perspective let's see what happens on a slow device so I enable the CPU throttling four times slower you can see that it does starter a little bit but it's mostly green and it tries to catch up to of my typing even though the device is slower compared to the synchronous version where it just stutters on every keystroke of course in real apps you often can optimize updates specifically so maybe only part of your app updates and so you can just update those components and avoid a large update but not every there are also scenarios where you just need to mount and you have a tree so I will unmount this chart completely and then mount it again with froth enabled so that's simulating a slow device and you can see that it hangs every time and while it's while it's rendering the chart nothing is interactive so I can actually click on this clock to simulate an interaction but while it's mounting it doesn't register my clicks now debouncing doesn't help us here because d bouncing is only helpful for updates but here I'm just mounting a huge component tree so let's compare this with asynchronous mode and I still have the throttle and a enabled so that's emulating the slow device so in asynchronous mode you can see that even though it Strutters a little bit it doesn't go into red and interestingly the circle stays interactive so I can actually I can start mountain I can click on this interact with this so the whole app is still working while the rendering is mounting in fact I can even start typing in the input and it's going to update to my type in so that was the CPU demo [Applause] and I want to emphasize that this is not about the charts or the inputs we've built a generic way to ensure the high priority updates don't get blocked by low prior to update and in this particular example high priority update was updating the input and a low priority update was rerender in the chart but it could have been any kind of react component for example a feed story that gets loaded and we don't want to freeze the scroll while we'll load in new items and defeat and we call this feature time slicing so it doesn't block the Frog the thread while it's rendering and if my device is fast enough it feels almost like it's synchronous but if it is slow then it feels at least it feels responsive so it adapts to the device thanks to browser exposing a request idle callback api that we use for that also notice that only the final state was displayed the update the rendered screen is always consistent we don't get artifacts of slowly rendering something that is going to cause a junky user experience we only flush when the low priority update is ready and you might think oh maybe I changed those chars to like make it's probably a lot of work to make charts this chart component worked like this but actually I just used it a ready-made component from NPM I didn't make any changes to it so we can look at the code and it's just a run a regular render method I have a chart component it renders components from NPM I pass data to it and I call set state and I use a special flag to tell react that it's is a low priority sad state and personally I've found it very helpful to use version control as a metaphor for this so when I didn't know about version control and I would just modify the files as I've worked on them hopefully I never like did anything silly that I can't undo so I would just work on a feature in my application but then if suddenly in the middle of working on that feature I need to fix a bug now I can't do it because I only have one version of my tree so I have to finish working on the future first and this is kind of how react works without time slicing the react that you know is that it can't interrupt the lunk update but when I learned version control I learned to work in a branch so I could start working on the feature working it in the branch but then if I need to do an urgent bug fix I just do it and master and then I can rebase the branch on top of that and so this is pretty much how react works with time slicing except that you don't have to rebase anything and react does that work so reactive term is how to apply a low-priority update on the top and it can continue working and then flush when everything is ready just like I can merge the branch when it's ready so we'll look at what we have could do better at the CPU side what about the i/o data fashion and code splitting I have another demo that's that's the fun part [Applause] all right I built a movie app so you can see this is the app it has a list of movies I can click on a movie it shows the detailed page were with movie details and the reviews and that's basically pretty much everything that it does so it has an app component at the top the trenders either movie list from movie list page which is this page or the movie details page which is this page so there is just to kind of pages here and the data is currently absolutely hard-coded so there's like a Jason with with the array of those things and we take the data by ID from the Jason so what if I wanted to change that to fetch data from a remote API let's go to the movie page component I'm going to remove the hard-coded movie details trace and import and instead I will import fetch movie details from API alright and I'm going to use another function that I'll import from the future again the exact API doesn't matter it may change most likely so I will call it create fetcher for now then I'll go through the movie details component so currently movie details reads from JSON object but I'm going to do something different I will create something called a fetcher so I'll call it movie details fetcher equals create fetcher and I will pass my promised return the function fetch movie details through it now the next step is going to be a little bit controversial so if you know react you probably know that you're not supposed to do data fetch and in renderer so in this talk I'm going to ban this rule a little bit and I just want you to follow along with it and see where it leads us so when react came out it was pretty controversial I think we can make more controversial things all right so I have this fetcher object and it works as a cache it has a single method called read so I'm going to call movie details fetcher that read and pass the ID so what's going to happen is that when a reactor enters the movie details component it will try to get this data from the cache but the TV is not there because it's not fetched yet so reactor is going to fetch the data and Rehab is going to prevent the entire update from occurring until the data is ready there is just one more thing I need to do I need to tell react that is actually ok for the transition from this page to the details page to be asynchronous so again the exact API is probably going to be different but here in the movie click where it says state show detail true I will call something called differs at state with the same state so let's see if that works I click on an item it waits and it loads and if you don't believe me I actually built a small debugger here so it shows the pending requests and how requests happen so if I remove everything from the cache and I click on the movie there is a request here and when it comes back react renders the detail view now you might think oh there must be a race conditions and maybe you think that the screen is not interactive well as fashion no it's it's interactive I can click here I can click here it's going to load the right one now it's in cache I can go back I can click on this movie it's in cache so it renders instantly however what if the latency is high what if their network request takes a lot of time like in this example three seconds but it could have been like 15 seconds so now if I click on a movie it seems like nothing is happening if you don't have the debugger open so that's not a very good user we can improve it so I'm going to import something else from the future it's very convenient to have access to the feature I'm going to import the component called a placeholder and I'm going to say that if anything inside the movie page is not ready we're gonna render a placeholder if the movie page takes more than a second and a half to load so there's a delay milliseconds argument then I want to show a spinner so what we are is going to do is going to try to render this component but if any of its child is going to render as much of the tree as it can but if any of the children are waiting for a single dependencies is going to wait for those children and if it takes more than this amount of time is going to display the for the placeholder until those dependencies are resolved so let's see how this works I click on a movie in this case my default latency is 1 second so it actually feels almost instantaneous so I don't see the loading indicator but if the latency is high 3 seconds and I click on a movie then it shows the the placeholder and then it shows the real thing when it's ready here is another interesting thing even while it's showing the placeholder the app is fully interactive it is never frozen so I can pause all new requests start a fashion imitate the fetch it takes a long time but say I want to go back I can actually go back so the whole the screen is always interactive now which has fetched the details but what if we want to fetch the reviews as well to do that I'm going to back to movie page component and I'm opening the let me import remove the hard-coded chase on import and instead import fetch movie reviews and I'm scrolling down to my movie reviews component that currently reads it from Jason and I create movie reviews fetcher great fetcher with fetch movie reviews and again I just call read I said sorry movie reviews fetcher dot read for props idea so move your reviews and movie details are siblings but the reality is going to wait for both of them before continuing so let's see if the latency is 1 second is waiting for both but wolf resolved in time so it doesn't display any intermediate loading states and doesn't the page doesn't jump with spinners but let's say that I pause near request a start fetching I'll let the reviews come through first while reactor can't render reviews alone it's important that the screen is always consistent with what's in the render methods so react is still showing the placeholder but when the details of the movie are loaded this is when it shows everything together now this may be fine but there is a downside what if I actually don't care about the reviews that much and I don't want to delay showing the details if the details told it first well to do that I use the placeholder component from the future so I can wrap the movie reviews component in a placeholder and I can say that if the movie review specifically took longer than a second to load since the interaction we actually don't care about them that much and we're going to show another spinner with a medium size let's see what happens so I pause all new requests start loading a movie and allow the details first it shows the details but the reviews are still loading and when the read is already it shows the reviews and again there are no risk conditions I can go back I can clear this I can start fetching this start fetching the reviews go back well here start afresh in the details it knows exactly what's the right thing to do and it respects the props that I passed through it but we can still make the user experience better for example when I just click if the delay is less than a second it's nice that the screen pops in when is ready but before that happens I don't have any visual indication that something's happening so can we fix that yes I will go into the app component and I will import something else from the future it's called loading so this is not the final API this actually this API is most likely to change but for now loading is just a component that gives me a render prop cold is loading that lets me decide what to show for now I'll copy paste what I already have here so either the detail view or the ListView but I already prepared my movie list page in a way that I can pass a load and ID through it and it will show an inline spinner so for example if I pass loading ID equals 1 it shows a spinner like this if a passcode and D equals 2 it shows the spinner on the second movie so what I'm going to do is I'm going to make loading ID and argument to render list and I'm going to call render released so if we are currently loading which is what we wanted to ask react then I just pass the current idea otherwise I pass null and I can even remove the the main placeholder now let's see what happens so now when I click it shows an inline spinner and again no race conditions I can click here then click here it shows the right thing the screen is always interactive and now this is cached so this is all cool but we can still improve the user experience even further for example currently we show the the movie page below the code for the movie page right away but we don't actually need it until we click on the movie so I'm going to replace this with a component that does code splitting so I'll call it movie page loader and I define it above it takes the props and passes them to movie page so if we are code splitting do we need to show a spinner while the code is loading or does a question even make sense if we have these new primitives that's him I'm going to import create fetcher again and I will create a movie page fetcher to fetch the movie page I will use the dynamic import syntax so I will return a promise that returns import to movie page and I remove the static webpack import so it's not going to be in the initial bundle finally to get the movie page component I call the read function on the fetcher and read the default default property from the module because it's the default export so I'll see if that works I click here there is no global loading indicator if the request takes fast enough yeah just edit code split into my app but if the request is slow oh I guess I removed the fallback so yeah that's not gonna work but we can check that this actually did something so if i refresh I clear the network top and I press you can see that there is a chunk here so you can see that this component truly was loaded with collision there is still one improvement to the user interface that I can make her you might have noticed that this movie has a taller posture than other movies let's say that we don't know their sizes immediately so when I click on it for the first time the page jumps a little bit when they when they movie loads so can we avoid showing the page until the image is ready well we can go to the movie page component and find the movie poster component that renders an image and I will create my custom image component with capital I the choice renders the browser image except with the twist I create an image feature which is a fetcher now I need to return a promise so return a function that returns a promise that resolves when I create a browser image object to preload the image and what that image loads I resolve my promise and I started the loading process and now I say that the source is image fetcher that read prop source I'm bad at this right yeah this should be an argument because I pass it to the wreath so it's going to come out here now if I click on it that didn't work okay it's a live demo some things don't oh right I forgot to use my image component that's why you should let look at the lint warnings so let's use the image component now I'll click on it and jumps on the page when the image is ready and this was the IO demo [Applause] we've built a generic way for components to suspend rendering when they load asynchronous data or dependencies or really anything asynchronous and we call this feature suspense you can pause any state update until the data is ready as specified by the components and you can add agent load into any component anywhere deep in the tree without clumping all the props and state and hoisting it up and using readouts or anything you usually do for that and on a fast Network the upside is that you can make it appear very fluent and almost instantaneous without the cheran cascade of spinners that appear and disappear all the time but on a slow Network you you can be intentional about design in the loading States and not just let them be artifacts of how the code is written in study explicitly design which load and States you want the user to see and how brenner of course they must be and there is both a high level and a low level API so the API that I showed you is a high level reference implementation that we're going to provide but there is a lower level API that libraries can use to integrate with this and again I found it helpful to use version control as a metaphor so when I use version version control and I start working on something and do this on a branch but sometimes maybe I can't continue working on the feature because I'm waiting for the designer to give me the final design so I put that work aside and I can do something else and this is how react suspends works is that react knows that these some of the children need some async dependencies so it just suspends that tree but it can still handle a higher priority event so this is why I was able to click on everything and continue navigating through the app and later just like I can rebase my old branch when I finally have the designs on top of the master react rebuses they suspended update and can continue when the async dependencies are satisfied and then committed to the Dom so coming back to my question how does how can a reaction able better user experiences for people with different devices and different networks we think that time slicing helps the CPU case and the the saucepans feature helps the i/o case is that we can be more intentional about designing for slower devices and how they should behave but we can also provide better experiences of past devices and you can see that there are a lot of similarities between these two these two axes so this is why we don't really think these are separate performance problems we think that both the problem the main problem here is not the performance but scheduling and the solution has to think about the scheduling and so we call this see the features async rendering in react and our goals is to let app developers adapt to users constraints such as device and network to make fast interactions feel instant without the janky things popping out of the screen and make slower interactions feel responsive and we designed intentionally and importantly this is still the react you know this is still the component declarative component paradigm now if he is reactive you probably that's what you like about it so it's not ready yet but these are not fake product like you saw me really using it so it's a real thing there is a pull request for this and there is more work to be done to enable this and to ship this as a stable feature and we hope to deliver it this year thank you you
Info
Channel: JSConf
Views: 115,117
Rating: 4.9792166 out of 5
Keywords:
Id: nLF0n9SACd4
Channel Id: undefined
Length: 33min 24sec (2004 seconds)
Published: Thu Apr 05 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.