firefox-devtools / firefox-devtools/profiler
jank when attempting to show many tracks
- Dominant language
- TypeScript
- Stars
- 1.5k
- Forks
- 491
- Avg merge
- 3d 5h
- Merged PRs (30d)
- 30
Description
Reproduction:
1. Download & load [this profile](https://github.com/firefox-devtools/profiler/files/9843536/pypy-compile.txt.gz).
1. Using the tracks dropdown, search for "pypy" and click "Show all matching tracks".
1. The UI freezes for 10 seconds while 300 tracks display.
The poor speed seems to be due to many unnecessary rerenders -- one commit for each track being shown. The following patch "fixes" the issue and brings the overall time to <100ms, but I doubt it's a safe change to make in general. #4118 may be relevant.
```diff
diff --git a/src/utils/resize-observer-wrapper.js b/src/utils/resize-observer-wrapper.js
index 67986f0e..d9de3aeb 100644
--- a/src/utils/resize-observer-wrapper.js
+++ b/src/utils/resize-observer-wrapper.js
@@ -8,6 +8,8 @@
// ResizeObserver for each use.
// This was inspired by the code in https://github.com/jaredLunde/react-hook/blob/master/packages/resize-observer/src/index.tsx
+import {unstable_batchedUpdates} from "react-dom";
+
export type ResizeObserverCallback = (DOMRectReadOnly) => mixed;
export type ResizeObserverWrapper = {|
subscribe: (elt: HTMLElement, ResizeObserverCallback) => void,
@@ -18,6 +20,7 @@ function createResizeObserverWrapper() {
// This keeps the list of callbacks for each observed element.
const callbacks: Map> = new Map();
const resizeObserver = new ResizeObserver((entries) => {
+ unstable_batchedUpdates(() => {
for (const entry of entries) {
const callbacksForElement = callbacks.get(entry.target);
if (callbacksForElement) {
@@ -25,6 +28,7 @@ function createResizeObserverWrapper() {
}
}
+ });
});
return {
subscribe(element: HTMLElement, callback: ResizeObserverCallback) {
```
┆Issue is synchronized with this [Jira Task](https://mozilla-hub.atlassian.net/browse/FP-587)
Contributor guide
Assessment
This issue has not been assessed yet.