Re: [csswg-drafts] [resize-observer] Notification after element is no longer referenced (#5155)

Commenting because I wasn't able to find this written down in the spec, MDN, etc., and had to discover this empirically: it seems that the current implementation of ResizeObserver in Google Chrome (v109.0.5414.87) will keep the ResizeObserver around even when the element has been removed from the DOM, and then the ResizeObserver will throw starting throwing a ton of errors (I suspect one error per frame?) and will not stop until the ResizeObserver is cleaned up or we call `disconnect()` on it. 

In my case, we're using a ResizeObserver in a React codebase to watch the height of an iframe, like so:

```js
export const IFrame = ({ src, title }) => {
  const [iframeHeight, setIframeHeight] = useState();
  const ref = useRef();

  return (
    <iframe
      src={src}
      style={{
        width: '100%',
        height: iframeHeight,
        border: 'none',
        padding: '15px',
        backgroundColor: '#fff',
      }}
      onLoad={() => {
        const component = ref.current.contentWindow.document.getElementsByClassName('embedded-page-content')[0];

        const observer = new ResizeObserver(() => {
          setIframeHeight(`${component.scrollHeight + 30}px`);
        });

        observer.observe(component);
      }}
      title={title}
      ref={ref}
    />
  );
};
```

We saw that when the React component gets unmounted (ex. we navigate to a different page), the ResizeObserver would fire off tons of errors.

Our solution was:
```js
export const IFrame = ({ src, title }) => {
  const [iframeHeight, setIframeHeight] = useState();
  const ref = useRef();
  const observerRef = useRef();

  useEffect(() => {
    // do nothing, but watch for the unload:
    return () => {
      observerRef.current?.disconnect();
    };
  }, []);

  return (
    <iframe
      src={src}
      style={{
        width: '100%',
        height: iframeHeight,
        border: 'none',
        padding: '15px',
        backgroundColor: '#fff',
      }}
      onLoad={() => {
        const component = ref.current.contentWindow.document.getElementsByClassName('embedded-page-content')[0];

        const observer = new ResizeObserver(() => {
          setIframeHeight(`${component.scrollHeight + 30}px`);
        });

        observer.observe(component);
        observerRef.current = observer;
      }}
      title={title}
      ref={ref}
    />
  );
};
```

-- 
GitHub Notification of comment by MustafaHaddara
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/5155#issuecomment-1381925380 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Friday, 13 January 2023 14:20:42 UTC