For that visit, it takes all these visits, it sorts them, it picks the slowest 25% of those visits and names the fastest of these slow 25% of visits as the INP for the page.
So, once again, what INP is, you measure every interaction, you pick the slowest 25% of interaction, then you collect all the slow visits, you pick the slowest 25% of all visits, and you get the INP for the page.
And this INP for the page is yellow or red in almost every React app I've seen. So, well, now, let's get back to our app. Our app is slow, and this makes INP also slow. And if I were to debug this issue, I would see that this issue, this slow typing into the filter is caused by React to render.
Here's what's happening in the app. So, when I type into the filter input, what happens in the app is React calls this set filter function which is a useState hook. That changes the state in a bunch of components, and that causes React to render all these components one by one until it's done. And this is what makes my input slow. This re-rendering is a stop the world operation. Nothing can happen until React is done. So, when I type on the keyboard, the page won't update until React has finished processing all the components, right? If it takes two seconds to process all the components, then the page won't update until two seconds later. This is the classic slow React render, and this is what makes interaction to an expanded bed in React apps.
Now, we have a performance problem, right? I type into the filter input, the app freezes for a second. This makes the interaction worse, this makes the user experience worse, this makes the MP worse. Now, if you were my question to you folks, if you were a developer of this app, how would you try to optimize this? How would you try to make this faster? Spoilers. Any other ideas? Debounce? What? Yeah, well, so, yeah, there are a bunch of stuff you could do. You could try wrapping some stuff with React memory, if there are any components that are rendering unnecessarily. You could optimize the component. You could virtualize the list, if that's a big list, and that's a big list. You could debounce and throttle. And one more thing that you could do, which React is introducing, you could also make updates non-urgent by using useTransition. What does this mean? So, with React 17 and below, every update that happens in the app is considered urgent. If you click a button, React has to handle the update immediately. If you type into the text field, React has to render the list of nodes immediately, and that's a stop the world operation. With React 18, however, your updates can now have a priority. Every update you make in the app is still by default urgent, but what React now also supports is non-urgent updates, and non-urgent updates automatically don't block the page, no matter how long they take. Let's see how this works. So, here is the code for my left sidebar in the app.
Comments