Skip to content

Commit

Permalink
Guide on preventing ResizeObserver errors (mdn#34658)
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh-Cena authored Jul 6, 2024
1 parent f291502 commit 4702911
Showing 1 changed file with 50 additions and 1 deletion.
51 changes: 50 additions & 1 deletion files/en-us/web/api/resizeobserver/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,62 @@ const resizeObserver = new ResizeObserver((entries) => {
}
});

window.addEventListener("error", function (e) {
resizeObserver.observe(divElem);

window.addEventListener("error", (e) => {
console.error(e.message);
});
```

As long as the error event does not fire indefinitely, resize observer will settle and produce a stable, likely correct, layout. However, visitors may see a flash of broken layout, as a sequence of changes expected to happen in a single frame is instead happening over multiple frames.

If you want to prevent these errors, the solution depends on what your intended effect is. If you actually intend to have an infinite loop, you just need to defer the resizing code in your `ResizeObserver` callback to after the browser repaints. You can put it into a [`requestAnimationFrame`](/en-US/docs/Web/API/Window/requestAnimationFrame) callback.

```js
const divElem = document.querySelector("body > div");

const resizeObserver = new ResizeObserver((entries) => {
requestAnimationFrame(() => {
for (const entry of entries) {
entry.target.style.width = entry.contentBoxSize[0].inlineSize + 10 + "px";
}
});
});

resizeObserver.observe(divElem);

window.addEventListener("error", (e) => {
console.error(e.message);
});
```

If you don't intend to have an infinite loop, you should make sure your resizing code does not trigger the resize observer callback. There are many ways to do this, such as by setting an "expected size" and not resizing if the size is already at that value.

```js
const divElem = document.querySelector("body > div");
const expectedSizes = new WeakMap();

const resizeObserver = new ResizeObserver((entries) => {
requestAnimationFrame(() => {
for (const entry of entries) {
const expectedSize = expectedSizes.get(entry.target);
if (entry.contentBoxSize[0].inlineSize === expectedSize) {
continue;
}
const newSize = entry.contentBoxSize[0].inlineSize + 10;
entry.target.style.width = `${newSize}px`;
expectedSizes.set(entry.target, newSize);
}
});
});

resizeObserver.observe(divElem);

window.addEventListener("error", (e) => {
console.error(e.message);
});
```

## Specifications

{{Specifications}}
Expand Down

0 comments on commit 4702911

Please sign in to comment.