React concurrency with Ivan Akulov === [00:00:00] Hi there and welcome to PodRocket, a web development podcast brought to you by LogRocket. LogRocket helps software teams improve user experience with session replay, error tracking, and product analytics. Try it for free at logrocket. com today. My name is Paul and joined with us is Ivan Eklov. He is a web performance engineer and consultant over at PerfPerfPerf. Yes, that's Perf three times. And we're here to talk about React concurrency. And some of the interesting features that are coming up with react 18. Welcome to the podcast, Ivan. Thank you. Hi, Paul. Very nice to meet you. And very honored to be at this podcast. We're honored to get to talk with you. Like you're an expert in very niche areas of the bleeding edge of some of the most popular patterns at web development. And we're here on the podcast to try to distill this down for people that maybe don't have enough time to look into the source code themselves or all these [00:01:00] sorts of things for you to get in this scenario. Where you're like, Oh yeah, I can go read the source. Or, I really understand concurrency down to its nuts and bolts. Can you just walk us through how you got there? Did you start off in React? Did you start off back in the PHP blend? I actually started back in the Flashland uh, like the Adobe Flash So, back in school, I got introduced into Adobe Flash and I... Started doing some stuff in that, then weirdly I stumbled upon C and delved into that ground. But after coding for a couple of years in C I realized that it's very hard to find jobs in C because you need to know algorithms and I don't love algorithms. So, what can you do if you don't do C You could do web development or mobile development, but I didn't have a smartphone, so I went into web development and, I've worked as an engineer for multiple years across multiple companies. And at some point after spending half a year configuring WebPackets on [00:02:00] projects, I realized that I have some web performance expertise that I could offer to other companies. At that point I started consulting and I was lucky to work with some great startups and big companies like Google, Framer, et cetera. And I've been doing this for five years at this point and helping a lot of companies get faster. And I like this very much. that's a great repertoire to have. Once you say you're a Google developer expert, that's definitely puts a green stamp on your name. And. You can tell that you like what you're doing, right? Because you've been doing it for a while. Oh yeah, no, definitely. I definitely love it. I, absolutely everything that's like touches performance and front end performance in particular. So we're going to be talking about , react concurrency. And specifically you mentioned things about time slicing. Which is like an older feature in react. It's not necessarily the newest and greatest for people who don't know what time slicing is and how it speeds up your application. Why is that a feature that you might find in some apps that are pushed out [00:03:00] today? So this is actually a really cool innovation that. React introduced into the popular web development. Maybe it was present in some other like stacks in some other framework, like non web frameworks. I'm not sure, but the idea is that like when you're writing some JavaScript, and you have some button and you want to click the button and that on click. Handler, changes something in the app, like re renders, for example, replaces completely one page with another page. What typically happens is you click the button and then if the re render is large, the page just freezes for like half a second. you have most definitely seen it if you interacted with any heavy app or heavy site. So what time 18 is it. Takes that work and it slices it into chunks of five millisecond, 10 millisecond tabs to give the browser a way to handle any user input in between the rendering. So with time slicing, now, if you click the button and the button[00:04:00] re renders the whole page and the user tries to interact with the page, tries to click some other button while that page is rendering. The browser will be able to handle that input right away, and the page would not feel frozen, the page would not be frozen, and the user experience would be much better. But it does not really work out of the box. Also, you need to actually tell React to use it. And this is on the client side, right? This is for the browser, painting my stuff. Oh yeah, no. Yeah, correct. And to me, that really reminds me back to like operating systems class. It's like the CPU scheduler. We have different types of events, like you coming in and there's some interrupts, right? Oh, you're pointing at me. That means there's some good stuff happening, but what's, what. Yeah. But that's like precisely the metaphor that the React team actually used in the docs. So the idea is that React rendering now works like a CPU. So, like back in the old ages when the CPUs only had one core, but you wanted to run. Multiple [00:05:00] apps at the same time. The way CPUs have handled that is they would switch between the like several apps very quickly, like multiple times per second. And that way, if you have two apps running side by side and you try typing like in the first app and then clicking the second app at the same time, or two apps try running the same thing side by side, even with one core, the CPU would be able to process both things happening at the same time, like the, it would not get blocked by. This stuff that's happening in the first up until it completes. And that's precisely what React is doing to web development. You could have multiple updates, multiple branches of updates running at the same time and React would just jump in between them until it has no more work to do. And it also, it would also prioritize more important stuff like synchronous clicks or less important stuff. I don't know, background updates, you just need to tell React that some update is a background one, a low priority one. So you have like this threading. Can we call it threading or no, we'll call it scheduling. We'll call it scheduling. Right on a, on a, I'm actually, I'm actually curious I don't know what's the metaphor in [00:06:00] CPUs when it jumps, I don't know, context switching? So given that we're just switching, we can think of it like a scheduler. How is this one line of thought, this one line of execution different? This time slicing. How's it different from concurrent concurrency? Because when I hear concurrency, what's coming up in react, I think about two things happening at the same time, which is inherently different. So tell me if I'm wrong. Tell me if I'm right. Ivan, what's the difference here? Oh yeah. So these are actually the same thing. So the idea is that React went through several rebrandings of this feature back when. This was introduced in 2018, when Dan Abramov gave the talk, , Beyond Rack 16 or something like that. The way he introduced this, he called this feature time slicing. But then just a month later in the next blog post in the record blog, that time slicing was right during named into I seen rendering and then over the next several years, I seen rendering [00:07:00] was renamed into concurrent mode and then concurrent mode was renamed into concurrent features. And there were like multiple reasons for this. So like I told Trex and actually asked Dan Mabromov just to do on Twitter as I was preparing for the podcast. Like, why was time slicing renamed? And. Time slicing is actually a part of concurrent features. So you you get this huge box with concurrent features written in it with a bunch of features in it. And one of the features is time slicing, which is precisely taking this huge chunk of work and slicing it into chunks of 5, 10 milliseconds. Okay. Gotcha. So it's like a subset of this grander box of tools that we have that we can call concurrent rendering. Yes. Understood. Okay. So under the hood, if we want to look at how the actual. Could we call it slicing? How the slicing happens, how React thinks about divvying up the rendering on the client side. Does it choose top level items on the top of the page before bottom level items when it slices these up into five? [00:08:00] Yeah, how does that process happen? How does React decide or not decide? Can you as a developer have a hand in how it decides? Oh, yeah. And so, by the way, , to add a bit on like this concurrent features versus time slicing I might be a little fuzzy here. This might not like perfectly match the history of I was not through the whole process. So like that parts I'm 80 percent sure I'm right about this concurrent features versus time slicing explanation. Just for if anyone decides to comment on Twitter or Hacker News as it happens But I would actually appreciate that comments in this correction, but yeah, the idea with our time slicing, the idea with concurrent rendering is that by default in the past in Direct 17 and Direct 16 and all the past versions of React, all the updates that were happening in the app, they were urgent. So you would click a button and React would go and process that updates. Right away, so like you would click a button or you would click your type into an input and [00:09:00] that would cause a thousand components to render and rect would go and render these thousand components right away and it would keep. Re rendering these components or like it would keep processing this re render for all the thousand components all the way until it's done. And only when it's done, it would finish executing the work and it would give the control back to the browser. So the browser could process the further input. So the way it works in React 18 now is that all updates by default are still urgent. So whenever you click a button that schedules a thousand components to render these thousand components are still processed. at the same time, but you could take some update or you could take some state value and you could mark that update or you could mark that state value as non argent and if you do that Then what React is going to do is the next time that state changes React is going to take that state and it's going instead of Processing all this stuff at the [00:10:00] same time. It's going to take that state update and it's going to start processing it Rendering that re rendering some components and then once five milliseconds pass it would stop rendering the components schedule Some work to be resumed in the next frame like with some basic set timeout zero or some other hacks that it uses in the There are like three three things that it uses in the sources and it would give the control back to the browser And then the browser would process any user input that's pending render any updates on the screen to do whatever stuff it needs to Do and then when the next frame starts React, the browser would call the callback that React has scheduled like the set timeout zero and React would keep processing the next components. And then five milliseconds later, again, it would give the control back to the browser and again, pick up the control in the next frame. probably kind of hard to imagine. Like it really clicked for me when I just saw it in DevTools , but the way you enable it and the way you could also see how it works in dev tools, how like this big chunk of work is actually split into a lot of tiny chunks of works [00:11:00] is take, I don't know, render a thousand of components. Then add some states that would force all these components to update for example, render a thousand of buttons that would render some number, right? And then when you click some button, that number changes in all of the buttons and then wrap that state update with a function called start transition that you could import from React. And then if you do that, and if you see how that looks in DevTools with start transition and without start transition, if we have. enough buttons you would see how the Basically see the difference how there's one huge task in the DevTools that blocks the main thread that blocks the page and Prevents the browser from doing anything while it's processing versus a thousand of tiny tasks where each just processes renders Just a few components at a time. So if I may ask a question, Ivan, one thing that caught my attention is you say in order to interject into the [00:12:00] sliced rendering process here as React divvies this up, I have to mark maybe a state update as non urgent. That's an interesting use of words. Because I would think that is quite urgent. Oh, yeah, so, I know I think the The primary thing that you need to learn as you move to React 18 and adopt these concurrent features is that like some updates are more important than others, right? I call them as urgent and non urgent. React like high priority or low priority. You could also call them as like synchronous and non synchronous, but the idea is that like when you have an app and let's take , a filter, for example, right? You have a filter, you have a filter inputs, and you have a bunch of. I don't know, blog posts, for example, that it filter filters. And so when you type into the filter, two things happen. First, the input value updates. So for example, I typed a, and the input updated and the input showed a, and then the list of the blog posts updates and showing all the blog posts that include [00:13:00] like a in it. And so if we look at this, like in most of the apps today, both of these. Pieces of app, both the inputs and the lists are going to be controlled , by a single piece of state, like called, for example, I don't know inputs, input value, or like filter value, right? And that's very logical. , you have a single bit of state that controls everything. So you have this in the app you would probably have this single bit of state that controls both the input and the list. But now, imagine that you have a really huge list of blog posts. For example, 10, 000 or 100, 000 of blog posts. And every time you're typing to that input, You have to render a lot of blog posts, and thus the typing is really slow. And so at this point, if you look at it from the user perspective, there are actually not one bit of state, but two bits of state that the user cares about. The first bit of state is the input, where the user types, which shows what the user has typed, what the user is typing. [00:14:00] And the second bit of state is the actual blog posts. We show like the result, the results of the filtering and to the user, those are two different bits of data and to the user, they actually do not have to update at the same time. And so what we can do with rectitine is we could take this single bit of state called filter value or whatever that controls both the input and the list of blog posts. And we could split it into two bits of state. And then when we're updating the second bit of state that controls the block posts, we could wrap that update, literally wrap that setState function, right? Take that setState function that updates the block posts, the list of block posts, and wrap it with startTransition. It's a function that you import from React, or it's a function that you get if you call a hook call useTransition. So both these are two equivalent ways to use it. And if you do That would tell React that second update is non urgent, meaning React [00:15:00] can take it and React can render it in the background, not giving the control back to the browser and not applying any changes to the screen until the render has fully completed. And in the process, the app would just stay fully interactive. So with that sort of pattern also assume and put the onus, the responsibility of responsible API fetching. On the developer, because this is something where if you were, if we didn't have time slicing, you were implementing this, you would see it get slow and you go, huh, maybe I shouldn't request for a new blog post, or I shouldn't filter in this grotesquely expensive way, because my input slowing down. But in this pattern, Every time you type, you'll go send a new filter, you send a new API request, but you got to be responsible in here and say, Okay, even though I'm visually updating fast, I have to use like debounce or something like this, maybe you could hide some inefficiencies in the way you're updating the state that could actually kill the [00:16:00] application. Have you seen this in the wild? Have you run into it in your own personal projects? , this actually a great comment because like in this example that I'm not talking about any network requests. So with network requests, , I need to think do, are we reloading the server? I don't know if it was a network request or probably just paginate. That's the easiest approach to both keep the serial loads small and also not render like a hundred thousand elements on the front end. But there's lots of stuff that does not... Interact with the server and still needs to render a lot of data, right? Maybe it's not the list of blog posts, but maybe it's some data intensive application that needs to render a table with a thousand rows. I know maybe it's some stock trading data or Maybe it's some, I don't know, SaaS app for like dentists where the person looks at all the clients that the dental practice has. So, and in all these cases, you might be interacting just with the local data and rendering a lot of stuff on the screen. And [00:17:00] that's where these non urgent updates Make the most sense to me because like you would have some really expensive Render that renders a lot of stuff and you could wrap it, but it's not But it's not like super urgent. There are like some parts of the UI that need to be updated first and you would wrap it with start transition and it would, the app would become much more responsive automatically. And that's actually one place where I really like to apply start transition. So my go to like my favorite heuristic with rectitine, like this switch in my head that I needed to make when I upgraded. to Rectitine when I worked with Rectitines that previously when it, when I would have some inputs that's produces a lot of updates and I would type into it and these updates would be slow. I would just put debouncing or put throttling in there, right? To make sure that like, , I'm not updating the I'm updating it just once per second, for example, only when I finished typing. So. Now, if I ever want to put a [00:18:00] debouncing or throttling somewhere, the next thought that I have in my head is, can I put start transition there? Because start transition is basically debouncing or throttling on steroids. It's really magical. . You can think of it as debouncing or throttling, but instead of giving it a single timer, timeout, like a second, you just pass The update that you need to do into it. And then react makes it work in a way that on a fast machine, it completes immediately on a slow machine. It takes as long as it needed, but as it needs, but it does not block the UI. So You can use it in a debounce fashion for some debounce cases, it sounds like, when you want to schedule something and not, and have it be non blocking. Precisely. Now, Ivan, I'd love to talk a little bit about some further features of react 18 that play into this like hydration, because that's been a hot button topic over the past years, as we've been doing hybrid render and all this stuff. Right before we hop into that, though, I'm just going to remember, remind all of our listeners [00:19:00] that this podcast is brought to you by log rocket. So log rocket is here to help you make applications faster and spend less time in. The developer tools and in the console , so logarchy can help you discover bugs with trends to surface issues that you might not have been able to find. And this way you can spend more time building a great app. So head over to logrocket. com today to try it for free. Now, Ivan, we're going to talk about hydration for a sec, because this for people we have on the podcast, we're talking about hybrid rendering, server side rendering, the static apps where you don't even render it. How does React 18 target hydration, make it less expensive, less computationally expensive, this is actually my favorite subject. So, if you're not familiar with hydration is basically a process where you take a server render tab and you make it interactive. And the way it works, the way, the reason it exists, and this is a bit of the necessary background that I need to explain to also show how React [00:20:00] makes hydration faster. In general, the way React renders stuff is It has three steps, right? The render step, the commit step, and the effects step. So, on the first step, on the render step, whenever you update something with the app, whenever you do any kind of render, Rack takes the updated components, it executes them, because rendering the component is literally taking the component function and calling it, and as a result, it takes some JSX that it basically converts into a virtual DOM. That's the first step. On the second step, on the commit step, React takes all that virtual DOM, React compares it with the previous virtual DOM, if there's any, and it applies the changes to the HTML, to the actual page HTML. And then on the third step, on the effect step, it runs... component edit mount, component edit update, use layout, effect use effect, stuff like this. So the idea behind hydration... Sorry, so all these three steps happen any time you change anything in your React app, any time React has to render anything. So the idea behind the [00:21:00] hydration... Is that hydration is basically an optimization. So in a typical app, in a typical client rendered app, so let's go back to 2014, right? We didn't have any server side rendering. We just had some basic reacts and we would build an app into one huge bundle. We would load the bundle on the clients, and then we would call react dom. render with the huge. DOM tree, and then React would perform these three steps, render, commit, and effects, right? So the idea behind hydration with server side rendering is that the commit step when you do server side rendering is actually unnecessary because you do not need to take virtual DOM and you do not need to apply to convert it into HTML. You already have the HTML. The server has just rendered the HTML and the server has just sent you. So you could just skip this step completely. So hydration is a performance optimization. It helps , server render tabs to be faster, but. Hydration can still be slow. [00:22:00] And the reason for this is that the render phase, the first phase that Rack does on every update and also on the first render, it can also be slow. The more components you have in the app, the more functions, the more component functions Rack has to call and the more time that will take. And in fact, in practice, like whenever I'm working with Rack tabs, hydration It's typically the, literally the most expensive react update, the most expensive JavaScript task that I see whenever I'm optimizing performance. interesting. Yeah. And the reason for this is like when you click some button and , some components updates, it's. Always only the components that have changed, right? But when you're rendering the app for the first time, like rendering it or hydrating it, all components on the page need to render. And that's by definition, more expensive than just rendering just the part of components and future updates. So this is really expensive. And this also worsens your. Lighthouse core, because it makes the total blocking time metric worse.[00:23:00] And it's also worse since your core vitals, because it makes first input delay and interaction to next paint worse. And so with React 18, actually one thing I'm really excited about which. With React team, one thing I'm really excited about is that you could take this initial render, which is very expensive, and you could tell React that, hey, take this initial render and do it in a non blocking manner. Render it as if it was a non Argent update and React would take that single huge task that renders all the components on the page that typically takes half a second, like the actual numbers I'm seeing on. On actual React sites, and it would split it into a bunch of tasks, just five, 10 milliseconds long. And so if the user now interacts with the page. While the page is hydrating, , that interaction would be way faster. And it the page would not be frozen while it's hydrating. So you can essentially apply some of these ideas we [00:24:00] were talking about to the actual hydration phase, make it non urgent. And then it's interrupt, interruptible, right? Yeah, precisely. So just like with this filter, right? When you're like typing and some part of the app is updated non urgently. The same thing you could apply to hydration and also make it hydrate non urgently. Amazing. And it sounds like this is just another thing to throw in the basket of benefits we can get from thinking about drawing things on the UI, like a scheduler, slicing it up. It's one of the many benefits we can get. And we've talked about benefits only. Ivan, are there any drawbacks you think that this is going to cause either the, in the development style we see from people or, further react if we're staying within the react bubble for like further arguments down the line within the react ecosystem. Oh yeah, definitely. So there's no free lunch, right? This is, that's a really cool improvement, but No free lunch yeah, it does not and I think [00:25:00] there are generally in general two challenges that I could foresee the first of them is like the ultimate limitation like You implement hydration in the RectCore, but you get some drawbacks that are, oh, sorry. You implement concurrency in the RectCore, but you get some drawbacks that come from this. And the second one is probably stuff more connected to misuse, like until it really clicks in your head. And it's a new pattern. It's it needs time to really click in your head. Until it really clicks in your head, there's a chance that I as a developer or somebody else on my team might apply it. Incorrectly, and that would actually lead to more performance issues. So, the first thing, the drawbacks that are inherent from the implementation, it's not really my opinion, like I, I'm not familiar with the React core enough to have an opinion on this, but the opinion of the Vue framework and the React framework, so both Vue and React looked at [00:26:00] React Concurrency back when it was introduced in 2018 and they experimented with it and they decided that hey No, we are not going to ship this and the reason for this is while concurrency is Really cool. Like it lets you take a huge chunk of fork and split it into smaller chunks of forks The chunks of work it by default just increases the complexity of the scheduler, increases the complexity of the framework core. So React before concurrency and React after concurrency are two different tracks. React after concurrency is. More complicated and rect after concurrency needs to do more work and those you're getting these new features but for every update you need to do the overhead the track has to do to process that update is Bigger and so the argument from Vue. js for example was that a Vue. js is just cheaper Like the Vue. js core just does less work for every update, so concurrency is not really needed. And B, remember what, how we talked about the render [00:27:00] phase and the commit phase? First React renders all the components, then React applies the changes to the DOM. So concurrency only optimizes the first phase. Applying changes to the DOM is not optimized. And so concurrency helps if you have an expensive render phase, if you have a lot of components, or if your framework core is so complicated that it has a lot of overhead and processing the rendering, but it does not help with the commit, does not help with applying the changes to the DOM. And so the Vue's argument was that Vue is already cheap enough that the render phase does not need to be optimized. And so it just doesn't need concurrency at all. The second kind of issues comes from until React concurrency folly clicks in your head, it's possible to misapply it or apply it and get not the performance result that you expect. I think there are two common pitfalls here. The first one is. Related to just the Origin versus non origin updates. So when you have some set state function, right? And that set state function [00:28:00] causes a thousand components to render, you could rub the set state function with start transition and expect that all these thousand components, they would be rendered in a non blocking manner. Basically the React would spend as much time as it needs, maybe a second rendering all these components, but to the user that would be very responsive, the page would not be frozen for a second. So there's one pitfall here. Which is, this only works if all of the individual components are cheap. If any of the components is expensive on its own, for example, you have a single component, like you're trying to render a thousand components, right? But one of these components takes half a second to render, like that component function takes half a second to execute, then the page would still be frozen for that half a second. And the reason for this is when Rack does time slicing, it can only slice in between the components. The way it works is Rect starts rendering Rect gets this queue of components that it needs to render, right? Non [00:29:00] concurrently, non blockingly. And then Rect starts processing that queue, and after processing every component, Rect looks at the timer and checks, Hey, have five milliseconds passed yet? And if, if five milliseconds have passed since Rect has started processing the components, then Rect basically set amount zero and gives the control back to the browser. And then like when set amount zero fires, Rect continues processing the components. So the challenge, however, is if any component is expensive on its own, this function that takes 500 milliseconds, right? The component function that takes 500 milliseconds. React would start executing that function and React would not be able to check the timer until that function execution completes. So you would render this component and the component to take 500 milliseconds. And you React would like, once the component completes. Rect would check the timer and Rect would be like, Oh, holy heck. It's been 500 milliseconds, not five milliseconds. Okay. Time to do a set timeout zero. And so Rect would do that, but it [00:30:00] can only do that once the component rendering completes. So luckily this case is uncommon in apps. So the way these apps work is you have a lot of components, like a huge component tree, but each individual component is cheap. So like in 98 percent of the cases, I would say start transition works as you would expect. But in some cases, for example, once I had a client that was it was a static websites, like a bloke or something. And they were, each block was after it, each block post was after it in Markdown and they were converting that Markdown to HTML straight in the React component. And that, yeah, that was fairly expensive. That was taking a hundred, 200 milliseconds. And that's a case where start transition would not help. So that's like one, one pitfall to be aware of. Another pitfall to be aware of is, so we talked about how start transition or start transition could optimize high duration, right? The challenge here. is that React is [00:31:00] smart about hydration. So if you try to make hydration concurrent, and you could do it in two ways, you could do it by wrapping the whole hydrate root call React DOM dot hydrate root call with start transition. That's one way, or you could do it by wrapping the, like some of the whole tree, the whole rectory or some parts of the tree with suspense. You don't even need to specify the full, but just wrap them with suspense. So if you do that. And React would start hydrating the app, React would hydrate the app concurrently, right? It would process some components, five milliseconds, give the control back to the browser. But then, if the user clicks something within the app, what would happen is React would take that click, and the moment that click happens, React would switch back to Argent rendering, to non concurrent rendering. So, basically... Let's say if the app has, for example, 000 components, right? 2, 000 rectangles. And then you click the page anywhere [00:32:00] after a thousand rectangles for protests in this non blocking manner, you click the page and the next thousand components, the next thousand rectangles, they would be processed in one go and they would freeze the page again. I'll send some links to the discussion in the React working group about this. , but you probably remember the cases when you went to some websites on a slow network and you tried clicking some buttons and these buttons were not doing anything right. Because the bundle has not yet loaded because they're like not there was no javascript yet on the page So you're clicking stuff you're like you're clicking the menu button and the menu was not opening yet And that's we grew used to it. But If you look at it with the fresh eyes, that's like really annoying. That's not a great user experience. So what React tries to do is it tries to avoid that as soon as it already can execute any code. So if you tell React to hydrate the page non urgently, concurrently, but then the user tries to interact with some part of the page that is not yet hydrated, React would take the, [00:33:00] that part of the page and it would hydrate that part. urgently so that after the hydration is complete, Rect can handle that click right away. So that Rect does not lose that click as if it happens when like the bundle has not loaded yet. But the challenge here, and here we come to the misuse, right? The challenge here is that this hydrating, this part Happens within a single suspense boundary. So if you have your whole app wrapped with suspense and you have no other suspense boundaries anywhere else, then the moment the user clicks anywhere in the app, the whole app will switch to regular blocking rendering. And that's going to be bad because to the user, the app would still lag and to your interaction to next paint metric which is going to be Vital soon, by the way, it's. It's also going to be a bad interaction and the way you solve this, the way you avoid this misuse is in general, you just look at some parts of your app and you [00:34:00] separate some logical parts. Like maybe I have a header, maybe I have a footer, maybe I have a menu, maybe I have some items in the list and you wrap each of them with a separate suspense block. And then if the user clicks in the header, then only the header is going to be hydrated urgently. If the user clicks in the footer, then only the footer is going to be hydrated urgently. Other parts of the page, it's still going to be hydrated non urgently. And so the page is going to be blocked instead of half a second, for example, if it took the whole page to hydrate. urgently to be blocked just for 0. 1 seconds if it's only the footer that was hydrated urgently. And that's much better. But you need to be aware of where these sort of rendering. Contours lie within your application in order to set the suspense boundaries in the right spots, right? And that's part of the proper use here that we're talking about. The like sort of the rendering boundaries of your sets of components. You have to be aware of what baskets of components in your app might take more time [00:35:00] versus less time so that you don't create these. Blocks my answer is no. So, I think this sounds very complicated because typically when I'm explaining it, I like to show the pictures and in the links that I'll send, you could actually see the pictures that the React team drew to explain this. But. You don't really need to know about which components take longer, which components take less time. You just need to look at your app, look at your page and just think logically okay, what, which sections this page has. And then take the sections and rub the sections with a span with suspense. And that's it. You don't need to know to have any technical knowledge about the page sections. You just need to like, imagine you're a designer. You would look at the page, like at the profile page, for example, right? Of some social network, and it'd be like, okay, that's a header. Okay, that's like the user banner. That's, that, that's like a post. That's like a sidebar. And just look at that and pick some parts that are... I don't know medium sized enough, like not too small for [00:36:00] wrapping everything with suspense to be annoying, but also not too large to mean that when the user clicks something everything blokes. Just look at these sections like a designer I don't know, like a user and rub this, these page parts with suspense and. That's gonna be it. Got. Oh, so it's more like from the user perspective about what I interact with in sections and you can think about it through this lens. Ivan, we are running up on time here. Before we part ways. If people want to hear more about your interactions with react or your thoughts, cause you mentioned that you like showing diagrams and stuff like this. Do you have writings anywhere or do you post anywhere? Oh, yeah. So I have twitter slash x accounts, Located at I am Akulov. So I am and my last name and I Regularly post some stuff there like bust from my consulting experience and just from my diving into like react internals and stuff And sometimes I also blog at 3perf. com. So , [00:37:00] if you want to see some case studies I don't know, like diving into notion loading performance or like diving into why a Spotify interaction is slow or just some tips and tricks that I've learned from my consulting experience, some bigger writing also like the best writing, the biggest writing also goes there. I mean, That sounds really interesting. I want to know why Spotify sometimes can be a little slow, so we can definitely throw those links down in the show notes if people want to check them out, but Ivan, thank you for your time. Thank you for coming on and enlightening us about time slicing and concurrent rendering, it's been a pleasure. Thank you so much for inviting me. , it's been a pleasure as well.