Lesson Description
The "Lanes" Lesson is part of the full, React Performance, v2 course featured in this preview video. Here's what you'd learn in this lesson:
Steve explains lanes in React Fiber, noting there are six lanes but developers control only two urgent ones. He highlights the importance of marking tasks as urgent or not to prioritize user actions like clicks and key presses. Steve also shows how lane assignment works, grouping updates by priority and applying changes to the DOM in the commit phase.
Transcript from the "Lanes" Lesson
[00:00:00]
>> Steve Kinney: There's effectively 6 lanes. You can make believe that there are only 2 and you'd be fine, and because there's only 2 that you can control. How about that? There are 6, only 2 do you have access to, so you might as well just pretend there's 2. I will tell you about the 6. I'm hoping it's 6 and not 5, but I'll tell you about the 6 in a moment. But there's effectively 2 urgent updates like user typed thing, user clicked button, like the things that are important, and then the things that are like we should do this but not at the expense of not representing user actions, right?
[00:00:37]
Like the big redraw of the graph, right, the sorting of the list, whatever, right, the thing that takes a really long time. When we say it's not urgent, that doesn't mean it's not important. It just means it's not urgent, right? And especially if the next keystroke changed the filter, right? Oh, we were going to filter all the Pokémon by C H A R and they took away the R by hitting the delete key.
[00:01:02]
That's important for what we were doing, right? And what makes something urgent or not urgent, you decide, right? So you're like, I don't know what any of these are. That means that everything is urgent, right? And what's the old saying, if everything's urgent, nothing's urgent, right? And so it's not necessarily that you mark things as urgent, is that you mark things as not urgent, right, and to say the things that are urgent can then pass through.
[00:01:31]
And there's some, get ready for some bitwise operators, it's going to be fun. But if you aren't doing that, then everything is urgent and there is probably some, if we look, when we see the measuring tools, some ways to get some quick wins in certain places the app, you're probably already thinking of. And they're different in every app, so on and so forth. OK, should I yield? Like I said, every so often, approximately after 5 milliseconds, but I say functions will block, so on and so forth.
[00:02:00]
And then are there higher priority tasks waiting? And the way that this works is that React Fiber has this idea of lanes, right? And so you can be in the fast lane. You can be in the lower priority lane, right? Things that are in the higher priority lane. We'll do a comparison and we'll see if they're more important, and we'll do those things, right? And like I said, there are about 6, we care about 2, we should know about the other ones because they're there.
[00:02:33]
It's just interesting, but we can kind of use these to get extra functionality for again, as we see this towards the end of the workshop, but I'm trying to see the ideas now. Shockingly little code, right? Like I said, some comes that are higher, we give it more attention. Cool. So this is how the lanes work. It is bitwise operators. The nice part is you're like, this confuses me and makes me sad.
[00:03:00]
You don't ever have to see this. So it happens under the hood because it turns out comparing two bitwise operators is super fast, taking two arrays and running through them, and then looking at objects on a, you know, properties on adjacent object, not nearly as fast as this crazy bitwise operator stuff. Nice part is, this might be the last time you ever have to see that, right? You're like, it's here to show you the concept, but beyond that, if that stresses you out, take a deep breath, I'm going to hit the next button on the slide.
[00:03:30]
And that was the last time you ever had to see that until you rewatched the course or something. But then you know it's coming and fast forward, you know. And there are, yes, 6 lanes. The two that basically, I guess, you know, input continuous lane and default lane are kind of the two kind of urgent ones, and that transition lane are the other ones that you can expose, and like 6 is kind of a lie because there can be up to 16 transition lanes, 6 categories of lanes.
[00:04:07]
How about that? That's truthier. And so the sync lane is like React only, you can technically call it with flush sync, which is like, I don't want any of this fiber stuff. I want to simply re-render the entire DOM, no matter what, opt me out of everything. I have yet to find a reason where I, like, there have been people on my team and people I've worked with like, I totally need to do this because, and if you ask them why 7 times, you will almost always find out that no one needs to do that.
[00:04:38]
But if you truly need to be like, no, I need to take priority, technically you can opt into that lane, but I'd rather you pretend that it doesn't exist because I've never seen an actual need to do it. Someone's like, I have one, they're probably right. So chime in and I'll be like, yeah, that's probably legit. The user actions, like, again, clicks, key presses, drag and scrolling. The user needs to feel, we all need to feel heard, right?
[00:05:06]
If the user does something, if they click on something, they hover over a button, and it doesn't get that CSS hover thing, they assume this is the worst app that they've ever used. Nothing makes people irate more than typing into an input field and watching it slowly show up, right? Like you're all thinking about the last time that that happened to you and you're like, I hated that thing. I've never, it's an HR app.
[00:05:32]
We all know it's an HR app. I don't know why that is. But like, that's what always, you know, comes to my mind. So those obviously high priority. The default lane is the normal stuff, right? And like, yes, you can say that those two are separate, but I'm kind of lumping them in together because you don't have any control over those two. React does it. The ones you have control over are this kind of putting stuff in these transition lanes.
[00:05:56]
These are lower priority lanes. This is the stuff like we need to do this, but we need to feel responsive and snappy to the user more than we need to do this. You don't get into that lane unless you say what I'm doing can go in that lane, right? And so if you're not opting in, your app isn't magically doing this, and React compiler is not going to help you yet, give it a few versions. Then there's some other ones, retry lanes, which is stuff that's failed, that's going to be given another shot at, obviously, that's gone a little low in the priority.
[00:06:34]
And then the idle lane, there are APIs that next time I do this workshop might be public APIs, right? Like right now they exist, they're not for you. They're not, there's no promises that they stay stable. There's like this off-screen and activity APIs which we're just saying like this is hidden from sight, so thereby it is not important. Now, when I say hidden by sight, that does not mean not in the viewport.
[00:06:57]
It does not mean the CSS class of hidden. It means totally off-screen somewhere, so on and so forth. Right now, you cannot access those, pretend they don't exist. And then if you're watching this 3 years from now and they do exist, I'm currently speaking from the past, telling you the future of me wasn't wrong, past me wasn't wrong, and whatever, in the future. Like they may exist at some point, but at the time of this recording, they don't.
[00:07:25]
And that's the way we're going to deal with this. So basically we have everything is basically urgent unless we say it's not urgent, right? Lane assignment comes, every assigns everything to the appropriate lane. It will group updates in the same lane together if it can, right, and then process the lanes from highest priority to lowest. If something comes in when it comes up for air, and it's higher priority, it will go switch to go do that, which again, could cause weird things to happen to your app if you were just blissfully unaware of that.
[00:07:56]
The goal is to have you, you should just get the default behavior, but you know, life's hard. Once we've rendered everything, we get to the commit phase, commits can never be interrupted because that is the act of changing the DOM, right? Like, once you have started to do stuff to the DOM, right, you kind of have to see it through. The act of not doing that gets you to a weird place where now the DOM got half updated.
[00:08:23]
So rendering can get interrupted, right, it can get stopped, it can get paused, things can slide in there. Once we start committing, like once we figured out the manifest of changes we're going to make to the DOM, and React starts doing that, it's going for it, right? Cool. And what it does is it takes a picture of, you know, everything that's kind of happening. It just reads as much information as you can about the DOM.
[00:08:48]
If you are still using class-based components, which, you know, they're still kind of for error boundaries, they exist. There is a get snapshot update that you can hook into at this point. I don't think there's an actual hook for it where you can kind of read some stuff as well. Then let's go ahead and change the DOM, does all the things it needs to do, and we'll run all the passive effects and cleanups for that.
[00:09:09]
And then there is a useLayoutEffect which we're not really going to talk about because, like, if you need it, you know you need it. And I also fear that if I tell you about it, you'll think you'll need it and you don't need it, right? If you're doing something like if you're a library author doing some cool rendering engine kind of thing, it's basically an ability before all of the stuff happens for you to hook in there and read the DOM and stuff like that, but it means you can block the entire commit process and cause a big problem.
[00:09:40]
So if you try to do your API calls in there or whatever, or anything expensive, you are stopping everything and being problematic. So if it is the only thing that you can solve your problem with, go for it, but otherwise, I didn't tell you to use it. Don't blame me and don't tell your team I did it. Do we make virtual DOM updates in the render phase? That, so the render phase is updating the virtual DOM at this point, right?
[00:10:03]
You've got the current tree and that work-in-progress tree, and the commit phase happens. Once the virtual DOM is settled, we know what needs to happen to the DOM. The commit phase is that taking that finished virtual DOM and applying it to the DOM. Great question. All right, finally, once we have shown the user everything that they need to show, then we will call useEffect. UseLayoutEffect happens before we render the DOM, which means we could gum up the entire works.
[00:10:32]
UseEffect happens after we've done it. And we've shown them everything and then we can go ahead and, you know, call any APIs and this is important. The reason I bring this up now versus otherwise I was going to have to pepper these things the entire day and it felt awkward, which is why if we're using something like useEffect for making API calls, it gets you into a pretty weird situation because you have to render the entire DOM.
[00:10:56]
Then you call useEffect to go get your APIs so that you can go render the DOM again, right? And for a while, if you're like, I do that on my app, and now I feel bad, don't feel bad. You didn't have a choice for a while. It was the effectively blessed way to do it. But now there are better ways, which is why we're spending this time together. Now, you might consider doing something like suspense, where, hey, on that render, as we were kind of going through the tree, I hit a suspense point.
[00:11:25]
All of those API calls will fire off immediately and they'll show the suspended DOM nodes, like the loading or whatever, will finish up. They've already started and then they can come back. And if they come back before React is done rendering and it can decide that it can do it fast enough, you'll get it immediately and not see that flash of nothing, and then all your stuff, right? And so ideally, stuff that was the best practice at one point is not the best practice anymore.
[00:11:56]
You didn't do anything wrong. Things just got better, right? And if you don't opt into these things, you get the same experience you always had. It's not like things are worse, but there is a better life, and we will talk about it today. So useEffect will always be called after the rendering phase when we have an empty dependency array. Typically examples calling APIs in a useEffect with the empty useEffect always happens after we've committed everything to the DOM, right?
[00:12:24]
So if it is like that useEffect with no dependencies that you only want to run once at the beginning, it will have rendered the component and all the children and committed that all to DOM and then call you useEffect, right? And the goal there is not like, well, now I have incomplete data. The goal was like, let's get something on the page. Let's not show them nothing, right, and not render, right, because suspense did not exist at that point, right?
[00:12:54]
And so you didn't really have much of a choice. It was like a trade-off that no one felt great about, and there are now other ways to do this as well. And there's nothing wrong, like, I'm not saying tomorrow you need to go refactor your entire codebase, but there are probably places where you can have some niceties because asynchronous stuff in a UI is the worst, right? Especially when you bring in TypeScript, but you don't really know if that's null or the actual value yet, and then you've got to pass down, it could be null or the actual value everywhere.
[00:13:21]
With suspense, you could be like, don't do anything until we have the value. This is not a course on TypeScript, but it turns out some of these things that make your app more performant also make your life way easier. So there's two reasons to do all this stuff, and we'll talk about the other ones at another time. But let's talk about the ones that are the ones you can really sell to everyone, which is performance, right?
[00:13:42]
You just pull out those reports that we've all seen like such and such company focused on performance and revenue went up. I've never convinced anyone in leadership based on those things, but they make me feel good as I present those slides. I decided to spare us all from those in this workshop. It's enough slides and talking as it was. I don't need to convince you that performance is important as you've already signed up for a React performance course.
Learn Straight from the Experts Who Shape the Modern Web
- 250+In-depth Courses
- Industry Leading Experts
- 24Learning Paths
- Live Interactive Workshops