-
Notifications
You must be signed in to change notification settings - Fork 46.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DevTools] Make Element Inspection Feel Snappy (#30555)
There's two problems. The biggest one is that it turns out that Chrome is throttling looping timers that we're using both while polling and for batching bridge traffic. This means that bridge traffic a lot of the time just slows down to 1 second at a time. No wonder it feels sluggish. The only solution is to not use timers for this. Even when it doesn't like in Firefox the batching into 100ms still feels too sluggish. The fix I use is to batch using a microtask instead so we can still batch multiple commands sent in a single event but we never artificially slow down an interaction. I don't think we've reevaluated this for a long time since this was in the initial commit of DevTools to this repo. If it causes other issues we can follow up on those. We really shouldn't use timers for debouncing and such. In fact, React itself recommends against it because we have a better technique with scheduling in Concurrent Mode. The correct way to implement this in the bridge is using a form of back-pressure where we don't keep sending messages until we get a message back and only send the last one that matters. E.g. when moving the cursor over a the elements tab we shouldn't let the backend one-by-one move the DOM node to each one we have ever passed. We should just move to the last one we're currently hovering over. But this can't be done at the bridge layer since it doesn't know if it's a last-one-wins or imperative operation where each one needs to be sent. It needs to be done higher. I'm not currently seeing any perf problems with this new approach but I'm curious on React Native or some thing. RN might need the back-pressure approach. That can be a follow up if we ever find a test case. Finally, the other problem is that we use a Suspense boundary around the Element Inspection. Suspense boundaries are for things that are expected to take a long time to load. This shows a loading state immediately. To avoid flashing when it ends up being fast, React throttles the reveal to 200ms. This means that we take a minimum of 200ms to show the props. The way to show fast async data in React is using a Transition (either using startTransition or useDeferredValue). This lets the old value remaining in place while we're loading the next one. We already implement this using `inspectedElementID` which is the async one. It would be more idiomatic to implement this with useDeferredValue rather than the reducer we have now but same principle. We were just using the wrong ID in a few places so when it synchronously updated they suspended. So I just made them use the inspectedElementID instead. Then I can simply remove the Suspense boundary. Now the selection updates in the tree view synchronously and the sidebar lags a frame or two but it feels instant. It doesn't flash to white between which is key.
- Loading branch information
1 parent
88ee14f
commit 4ea12a1
Showing
6 changed files
with
44 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters