-
Notifications
You must be signed in to change notification settings - Fork 18
ResizeObserver#observe() firing the callback immediately results in infinite loop #38
Comments
Duplicate of #7 ?
…On Mar 29, 2017 4:36 PM, "Lea Verou" ***@***.***> wrote:
I thought I'd post here first, in case this is intended behavior and not a
Chrome bug. Couldn't quite tell from the spec.
Take a look at the following code (live here
<http://jsbin.com/copiyel/6/edit?js,console,output>):
var div = document.querySelector("div");var resizeObserver = new ResizeObserver(entries => {
console.log("resizeobserver fired");
resizeObserver.disconnect();
// [Operation that would cause resize here]
resizeObserver.observe(div);
});
resizeObserver.observe(div);
This is a very common pattern with any kind of observer: Often you want to
monitor external changes to the DOM and as a response to them, you need to
make changes of your own that should not trigger the same observer because
that would cause a loop.
With Mutation observers, this pattern works fine. However, since
ResizeObserver seems to be firing the callback immediately after observe()
is called, this causes an infinite loop.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#38>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAZoLEl7zJ1hi43G2sH4yFW3vSxFbVpVks5rqurfgaJpZM4MtsCF>
.
|
Don’t think so. It would be a duplicate if there was no |
This is a bug. The infinite loop should have been prevented by depth limit. Filed Briefly looking at the code, this should not have happened. Glad you are looking at the API. We are planning on sending Intent To Ship soon, would love to hear any comments about the API you might have. |
As I mentioned above, it should not even get close to the depth limit, because it shouldn't fire immediately on If I want the same code to run both immediately when I attach the observer and in the future on resizes, I can just call it myself before attaching the observer and it would just be an extra line of code. However, if I don't want this behavior, there's no opt-out. Also, running the callback immediately once |
That is per spec. The reason is non-obvious (layout thrashing). See |
Hi Aleks, I've recently found that ResizeObserver fires the Could please confirm that this is an expected behavior because it definitely wasn't like that a few months ago. |
It is an expected behavior. If an element is resized in response to a notification, that generates a new expectation, which can't be delivered. This should have been happening all along. I am surprised that this was not the case a few months ago. There was a bug where garbage collection stopped all notifications, but this example would not have triggered it. What do you think should happen? |
Well, testing of the native implementation against tests for the polyfill wasn't failing before. At least not when I checked it last time. It's a shame that I've found it only now.
As far as I'm concerned, if it doesn't lead to an infinite loop then no exceptions should be raised. The most terrifying thing is that when RO gets enabled by default it will break quite a lot of existing implementations that rely on the polyfill. Unfortunately I don't know of any workaround to reproduce this exact behavior on the JS side. It doesn't seem to be possible to tell what triggered the resize of an element. |
Pardon my ignorance, but why does the JSBin example trigger an error, while this does not (or am I just missing it? Expecting to see it in the console...) In the example, the block still becomes 300px wide. My understanding is, RO sees that the observed element has triggered its own resize and quits queuing microtasks until the next frame. So the intended change happens, just a frame late. Is that correct? If so, why is that a big deal? |
Any update on this? |
? |
A note to everyone interested in this API. We've gotten feedback from developers who'd like to observe border-box rect. We are thinking of tweaking the API to allow observation of border box (possibly scrollSize too). We are hoping to have a proposal by October TPAC. |
I am using the ag-grid library which uses the My observation can be summarized in the following code snippet const observedElement
const siblingOfObservedElement
const observer = new ResizeObserver(()=> {
updateStyleOf(siblingOfObservedElement);
});
observer.observe(observedElement); When running unit tests of our product with Chrome Headless (all versions since 64) inside docker (debian jessie) the test suite breaks with a My questions: Our test suite will pass by changing the library source code to this: const observer = new ResizeObserver(()=> {
setTimeout(() => updateStyleOf(siblingOfObservedElement));
}); Interestingly by doing so, the observer does not trigger an additional callback. |
"loop_limit exceeded" notification happens when ResizeObserver cannot deliver observations. Here, height of #container depends on height of #target. If you are observing #container, and change #target height inside RO callback, you'll hit the error. #target resize will change #container height, which will trigger RO observation, which cannot be delivered because RO has already delivered notifications at this depth. This error is often benign. Seeing many of them would be worrysome, and might indicate an infinite resize loop. For detailed explanation of what this error means, check out #7 It is interesting that it only happens in headless, and that it is not consistent. From your example, sibiling's size affects observed's size. But why only sometimes? |
@atotic thanks for the explanation. I hoped there would be more to it. But in the essence it is clear. So i tried to reproduce the behavior https://github.com/giniedp/ag-grid-ro-issue Now i still dont know why it only breaks sometimes. But that is something the library developers have to sort out. |
Is there any way to catch this error? It is happening during unit testing, which is halting our test suite. I've tried |
Error gets reported to "window.onerror" like many other runtime errors. There is no way to "catch" it. |
I'm using Intern and there is now an issue for this case. My question is this: if this is a benign error that we should ignore, why is it being reported? Why do we need to redo tooling and such for non-errors? Can it be delivered as a warning instead? |
So if this is happening to you with cypress, @jennifer-shehane suggests:
And to mute Sentry:
From this discussion: quasarframework/quasar#2233 |
I thought I'd post here first, in case this is intended behavior and not a Chrome bug. Couldn't quite tell from the spec.
Take a look at the following code (live here):
This is a very common pattern with any kind of observer: Often you want to monitor external changes to the DOM and as a response to them, you need to make changes of your own that should not trigger the same observer because that would cause a loop.
With Mutation observers, this pattern works fine. However, since
ResizeObserver
seems to be firing the callback immediately afterobserve()
is called, this causes an infinite loop.The text was updated successfully, but these errors were encountered: