Skip to content

Commit 9293e05

Browse files
kfrederixKarel Frederixalexdima
authored
wrap handler for resize observer in requestAnimationFrame() (microsoft#183325)
* wrap handler for resize observer in requestAnimationFrame() (fixes microsoft#183324) * React immediately on first notification during an animation frame and only delay the second notification during the same animation frame --------- Co-authored-by: Karel Frederix <[email protected]> Co-authored-by: Alexandru Dima <[email protected]>
1 parent 9e927a6 commit 9293e05

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

src/vs/editor/browser/config/elementSizeObserver.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,42 @@ export class ElementSizeObserver extends Disposable {
4141

4242
public startObserving(): void {
4343
if (!this._resizeObserver && this._referenceDomElement) {
44-
this._resizeObserver = new ResizeObserver((entries) => {
45-
if (entries && entries[0] && entries[0].contentRect) {
46-
this.observe({ width: entries[0].contentRect.width, height: entries[0].contentRect.height });
44+
// We want to react to the resize observer only once per animation frame
45+
// The first time the resize observer fires, we will react to it immediately.
46+
// Otherwise we will postpone to the next animation frame.
47+
// We'll use `observeContentRect` to store the content rect we received.
48+
49+
let observeContentRect: DOMRectReadOnly | null = null;
50+
const observeNow = () => {
51+
if (observeContentRect) {
52+
this.observe({ width: observeContentRect.width, height: observeContentRect.height });
4753
} else {
4854
this.observe();
4955
}
56+
};
57+
58+
let shouldObserve = false;
59+
let alreadyObservedThisAnimationFrame = false;
60+
61+
const update = () => {
62+
if (shouldObserve && !alreadyObservedThisAnimationFrame) {
63+
try {
64+
shouldObserve = false;
65+
alreadyObservedThisAnimationFrame = true;
66+
observeNow();
67+
} finally {
68+
requestAnimationFrame(() => {
69+
alreadyObservedThisAnimationFrame = false;
70+
update();
71+
});
72+
}
73+
}
74+
};
75+
76+
this._resizeObserver = new ResizeObserver((entries) => {
77+
observeContentRect = (entries && entries[0] && entries[0].contentRect ? entries[0].contentRect : null);
78+
shouldObserve = true;
79+
update();
5080
});
5181
this._resizeObserver.observe(this._referenceDomElement);
5282
}

0 commit comments

Comments
 (0)