question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ResizeObserver loop completed with undelivered notifications

See original GitHub issue

Describe the bug We keep seeing thousands of these logs in our sentry bug tracker. It occurs in the window.onerror event listener:

ResizeObserver loop completed with undelivered notifications

Frameworks/Libraries used React 16.9.0

I’m using it in a hook useResizeObserver.ts:

/**
 * Inspired by ZeeCoder/use-resize-observer (MIT licensed).
 * @see https://github.com/ZeeCoder/use-resize-observer
 * @see https://github.com/juggle/resize-observer
 */

import { useEffect, useState, useRef, useMemo, RefObject } from 'react'
import { ResizeObserver } from '@juggle/resize-observer'

interface IUseResizeObserverProps<T> {
  ref?: ((instance: T | null) => void) | RefObject<HTMLDivElement> | null | undefined,
  onResize?: (size: { width: number, height: number }) => void
}

export interface ISize {
  width?: number,
  height?: number
}

const useResizeObserver = <T>({ ref, onResize }: IUseResizeObserverProps<T> = {}) => {
  // `defaultRef` Has to be non-conditionally declared here whether or not it'll
  // be used as that's how hooks work.
  // @see https://reactjs.org/docs/hooks-rules.html#explanation
  const defaultRef = useRef(null)
  ref = ref || defaultRef

  const [size, setSize] = useState<ISize>({
    width: undefined,
    height: undefined
  })

  // Using a ref to track the previous width / height to avoid unnecessary renders
  const previous = useRef<ISize>({
    width: undefined,
    height: undefined
  })

  useEffect(() => {
    if (
      typeof ref !== 'object' ||
      ref === null ||
      !(ref.current instanceof Element)
    ) {
      return
    }

    const element = ref.current

    const resizeObserver = new ResizeObserver(entries => {
      if (!Array.isArray(entries)) {
        return
      }

      // Since we only observe the one element, we don't need to loop over the array
      if (!entries.length) {
        return
      }

      const entry = entries[0]

      // `Math.round` is in line with how CSS resolves sub-pixel values
      const newWidth = Math.round(entry.contentRect.width)
      const newHeight = Math.round(entry.contentRect.height)

      if (
        previous.current.width !== newWidth ||
        previous.current.height !== newHeight
      ) {
        const newSize = { width: newWidth, height: newHeight }
        if (onResize) {
          onResize(newSize)
        } else {
          previous.current.width = newWidth
          previous.current.height = newHeight

          setSize(newSize)
        }
      }
    })

    resizeObserver.observe(element)

    return () => {
      resizeObserver.unobserve(element)
      resizeObserver.disconnect()
    }
  }, [ref, onResize])

  return useMemo(() => ({ ref, ...size }), [ref, size])
}

export default useResizeObserver

Smartphone (please complete the following information): E.g. one case

  • Device: iPhone
  • OS: iOS 13.4
  • Browser: Chrome Mobile iOS
  • Version: 80.0.3987

(But we also see this on Android, Windows, Linux, iOS safari)

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
TremayneChristcommented, Apr 7, 2020

Hi @tommedema this in an inbuilt feature to prevent infinite resize loops that will chrash the browser https://github.com/juggle/resize-observer/blob/master/README.md#resize-loop-detection

This happens when an observed element is resized again during a notification. This can easily happen when scrollbars appear, for example.

2reactions
TremayneChristcommented, Apr 7, 2020

No, it’s designed to be dispatched this way. You are receiving the error, because there is a genuine error - a resize loop.

I’m not sure what your size hook is doing, but, I see you are rounding values and then setting the rounded value back. If this is in the same loop as the resize notification, it will cause another resize on the element, because 254.4 !== 254.

Why do you need to round values?

Read more comments on GitHub >

github_iconTop Results From Across the Web

:0:0 ResizeObserver loop completed with undelivered ...
Technically this is a javascript error caused by a recursive loop within a resize observer. When you resize your browser window manually, or ......
Read more >
google chrome - ResizeObserver - loop limit exceeded
The browser versions that have been giving us this error are: Chrome: 63.0.3239 (ResizeObserver loop limit exceeded); Chrome: 64.0.3282 ( ...
Read more >
ResizeObserver - Web APIs | MDN
ResizeObserver loop completed with undelivered notifications. Note that this only prevents user-agent lockup, not the infinite loop itself.
Read more >
Trending client error: ResizeObserver loop limit exceeded
I see Special:Translate as a frequent URL but not the only one. A few possibly related errors: ResizeObserver loop completed with undelivered notifications....
Read more >
Tabulator Error ResizeObserver loop completed with ...
ResizeObserver loop completed with undelivered notification. Its not a python error so its definitely coming from javascript.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found