Sentry Answers>React>

React: ResizeObserver loop completed with undelivered notifications

React: ResizeObserver loop completed with undelivered notifications

Shivan M.

The Problem

In React, you may get the following error related to ResizeObserver:

Click to Copy
ResizeObserver loop limit exceeded

This may be confusing if you haven’t used ResizeObserver directly in your codebase.

In most cases, you can safely ignore this error if you are experiencing it locally and you’re not using ResizeObserver directly.

However, let’s look at some common workarounds and solutions both for React and using ResizeObserver directly.

The Solution

If you are using ResizeObserver directly and experiencing the error, you may need to verify whether your implementation follows the specification for the ResizeObserver interface.

Implementations should invoke resize events before the frame under observation is presented to the user. If a resize event occurs, style and layout are re-evaluated, which may trigger more resize events. To avoid infinite loops from cyclic resize dependencies, each iteration only processes elements deeper in the DOM. If a resize event doesn’t meet that condition, it is deferred and an error event is fired.

This happens to prevent the browser from becoming unresponsive, but it does not prevent the infinite loop.

If your code is such that the resizing loop is not infinite, ResizeObserver will eventually settle and your layout should be correct. In the case that the error is firing, you may see that your application layout changes incrementally rather than all at once, as resize events are being delayed across multiple frames.

In the following code sample, the ResizeObserver updates the width of the divElem in a loop over the entries (including the divElem itself). This causes an infinite loop, which causes the error message to repeat every frame:

Click to Copy
const divElem = document.querySelector("body > div"); const resizeObserver = new ResizeObserver((entries) => { console.log(entries) for (const entry of entries) { entry.target.style.width = entry.contentBoxSize[0].inlineSize + 10 + "px"; } }); resizeObserver.observe(divElem);

There are a few ways to stop the error from appearing, depending on your tech stack.

Workaround 1: Incognito Mode

To verify whether the error is caused by a browser extension, open your application in an incognito browser window, where no (or fewer) browser extensions are loaded. If the error does not occur in the incognito window without extensions active, you can assume that it was caused by an extension modifying the layout of your application.

Workaround 2: React and Webpack

If you are using React and Webpack, you can disable the notification from Webpack by modifying the configuration options for the dev server in webpack.config.js:

Click to Copy
module.exports = { //... devServer: { client: { overlay: { runtimeErrors: (error) => { if (error.message === 'ResizeObserver loop limit exceeded') { return false; } return true; }, }, }, }, };

Workaround 3: Cypress Tests

If you are experiencing this error when running end-to-end tests with Cypress, you can add the following code to your configuration to ignore the error:

Click to Copy
const resizeObserverLoopErrRe = /^ResizeObserver loop limit exceeded/ Cypress.on('uncaught:exception', (err) => { if (resizeObserverLoopErrRe.test(err.message)) { return false } })

Workaround 4: Sentry Error Monitoring

If you’d like to ignore this error in your Sentry reporting, you can add the error to the ignoreErrors parameter in the Configuration Options:

Click to Copy
Sentry.init({ ... ignoreErrors: ['ResizeObserver loop limit exceeded'] })

Understanding the ResizeObserver loop limit exceeded Error Message

In the browser, the ResizeObserver interface reports changes to the dimensions of a browser element’s content, border box, or the bounding box of an SVG element.

You might use ResizeObserver to change the font size of an element as a slider is moved (causing a <div> to change width), as illustrated in the following code taken from the official MDN documentation:

Click to Copy
const h1Elem = document.querySelector("h1"); const pElem = document.querySelector("p"); const divElem = document.querySelector("body > div"); const slider = document.querySelector('input[type="range"]'); const checkbox = document.querySelector('input[type="checkbox"]'); divElem.style.width = "600px"; slider.addEventListener("input", () => { divElem.style.width = `${slider.value}px`; }); const resizeObserver = new ResizeObserver((entries) => { for (const entry of entries) { if (entry.contentBoxSize) { const contentBoxSize = entry.contentBoxSize[0]; h1Elem.style.fontSize = `${Math.max( 1.5, contentBoxSize.inlineSize / 200, )}rem`; pElem.style.fontSize = `${Math.max( 1, contentBoxSize.inlineSize / 600, )}rem`; } else { h1Elem.style.fontSize = `${Math.max( 1.5, entry.contentRect.width / 200, )}rem`; pElem.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`; } } console.log("Size changed"); }); resizeObserver.observe(divElem); checkbox.addEventListener("change", () => { if (checkbox.checked) { resizeObserver.observe(divElem); } else { resizeObserver.unobserve(divElem); } });

In some instances, the ResizeObserver loop limit exceeded error message might be due to a browser extension modifying the layout of your page, or a library in your application that initiates element resizes outside of the scope of the ResizeObserver specification.

Additional Reading

  • Sentry BlogHow to identify fetch waterfalls in React
  • Syntax.fmReact Server Components
  • Syntax.fmWhy the jQuery Creator Uses React and Typescript
  • Syntax.fmListen to the Syntax Podcast
  • Sentry BlogReact Native Debugging and Error Tracking During App Development
  • Syntax.fmDiscussion on building native iOS and Android apps with React Native
  • SentryReact Error & Performance Monitoring
  • Sentry BlogFixing memoization-breaking re-renders in React
  • Syntax.fm logo
    Listen to the Syntax Podcast

    Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.

    SEE EPISODES

Considered “not bad” by 4 million developers and more than 100,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.

© 2024 • Sentry is a registered Trademark
of Functional Software, Inc.