211

大约两个月前,我们开始使用 Rollbar 来通知我们 Web 应用程序中的各种错误。从那以后,我们偶尔会遇到错误:

ResizeObserver loop limit exceeded

让我感到困惑的是我们没有使用ResizeObserver,我调查了我认为可能是罪魁祸首的唯一插件,即:

Aurelia 调整大小

但它似乎也没有使用ResizeObserver

同样令人困惑的是,这些错误消息自 1 月份以来一直在出现,但ResizeObserver直到最近才向 Chrome 65 添加了支持。

一直给我们这个错误的浏览器版本是:

  • Chrome:63.0.3239(超出 ResizeObserver 循环限制)
  • Chrome:64.0.3282(超出 ResizeObserver 循环限制)
  • 边缘:14.14393(安全错误)
  • 边缘:15.15063(安全错误)

所以我想知道这是否可能是浏览器错误?或者也许是一个实际上与它无关的错误ResizeObserver

4

10 回答 10

301

您可以放心地忽略此错误。

规范作者之一在对您的问题的评论中写道,但这不是答案,并且在评论中并不清楚答案是否真的是该线程中最重要的答案,也是让我很舒服地忽略它的答案我们的哨兵日志。

此错误意味着 ResizeObserver 无法在单个动画帧中提供所有观察结果。它是良性的(您的网站不会中断)。– Aleksandar Totic 4 月 15 日 3:14

规范存储库中也有一些与此相关的问题。

于 2018-05-17T08:53:07.403 回答
66

这是一个老问题,但它仍然可能对某人有帮助。您可以通过将回调包装在requestAnimationFrame. 例如:

const resizeObserver = new ResizeObserver(entries => {
   // We wrap it in requestAnimationFrame to avoid this error - ResizeObserver loop limit exceeded
   window.requestAnimationFrame(() => {
     if (!Array.isArray(entries) || !entries.length) {
       return;
     }
     // your code
   });
});
于 2019-11-04T21:45:12.967 回答
38

如果您使用 Cypress 并且遇到此问题,您可以在 Cypress 中使用 support/index.js 或 commands.ts 中的以下代码安全地忽略它

const resizeObserverLoopErrRe = /^[^(ResizeObserver loop limit exceeded)]/
Cypress.on('uncaught:exception', (err) => {
    /* returning false here prevents Cypress from failing the test */
    if (resizeObserverLoopErrRe.test(err.message)) {
        return false
    }
})

您可以在此处关注有关它的讨论。由于赛普拉斯维护者自己提出了这个解决方案,所以我相信这样做是安全的。

于 2020-08-21T08:34:44.453 回答
7

我们遇到了同样的问题。我们发现 chrome 扩展是罪魁祸首。具体来说,loom chrome 扩展导致错误(或我们的代码与 loom 扩展的某些交互)。当我们禁用扩展程序时,我们的应用程序可以正常工作。

我建议禁用某些扩展/插件,看看其中一个是否可能导致错误。

于 2019-12-18T00:18:33.383 回答
7

对于摩卡用户:

下面的代码片段覆盖了 mocha 安装的 window.onerror 挂钩并将错误转换为警告。 https://github.com/mochajs/mocha/blob/667e9a21c10649185e92b319006cea5eb8d61f31/browser-entry.js#L74

// ignore ResizeObserver loop limit exceeded
// this is ok in several scenarios according to 
// https://github.com/WICG/resize-observer/issues/38
before(() => {
  // called before any tests are run
  const e = window.onerror;
  window.onerror = function(err) {
    if(err === 'ResizeObserver loop limit exceeded') {
      console.warn('Ignored: ResizeObserver loop limit exceeded');
      return false;
    } else {
      return e(...arguments);
    }
  }
});

不知道有没有更好的方法..

于 2020-10-04T17:19:19.253 回答
4

添加去抖之类的

新的 ResizeObserver(_.debounce(entries => {}, 200);

为我修复了这个错误

于 2020-09-22T09:11:21.597 回答
1

https://github1s.com/chromium/chromium/blob/master/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc#L44-L45 https://github1s.com/chromium/chromium/blob/master/third_party /blink/renderer/core/frame/local_frame_view.cc#L2211-L2212

查看源代码后,在我的情况下,当调用 NotifyResizeObservers 函数并且没有注册的观察者时,问题似乎浮出水面。

GatherObservations 函数将返回 4096 的 min_depth,以防没有观察者,在这种情况下,我们将收到“超出 ResizeObserver 循环限制”错误。

我解决它的方法是让观察者生活在页面的整个生命周期中。

于 2021-08-06T17:37:00.303 回答
1

就我而言,“ResizeObserver - 超出循环限制”的问题是由于window.addEventListener("resize"React 的React.useState.

详细地说,我正在研究名为useWindowResizewhere the use case is like this的钩子const [windowWidth, windowHeight] = useWindowResize();

代码通过 useEffect 对windowWidth /windowHeight变化做出反应。

React.useEffect(() => {
    ViewportService.dynamicDimensionControlledBy(
        "height",
        { windowWidth, windowHeight },
        widgetModalRef.current,
        { bottom: chartTitleHeight },
        false,
        ({ h }) => setWidgetHeight(h),
    );
}, [windowWidth, windowHeight, widgetModalRef, chartTitleHeight]);

因此,任何浏览器窗口调整大小都会导致该问题。

我发现由于连接old-javascript-world(DOM 操作,浏览器事件)和new-javascript-world(React)而导致的许多类似问题可能由setTimeout.尽可能反模式。

所以我的解决方法是将 setter 方法包​​装到setTimeout函数中。

React.useEffect(() => {
    ViewportService.dynamicDimensionControlledBy(
        "height",
        { windowWidth, windowHeight },
        widgetModalRef.current,
        { bottom: chartTitleHeight },
        false,
        ({ h }) => setTimeout(() => setWidgetHeight(h), 0),
    );
}, [windowWidth, windowHeight, widgetModalRef, chartTitleHeight]);

于 2022-01-06T06:49:52.670 回答
1

该错误可能值得调查。它可以表明您的代码中存在可以修复的问题。

在我们的例子中,观察到元素的大小调整触发了页面上的更改,这再次导致第一个元素的大小调整,这再次触发页面上的更改,这再次导致第一个元素的大小调整,......你知道这是怎么回事结束。

本质上,我们创建了一个无限循环,显然无法将其放入单个动画帧中。我们通过阻止页面上的更改来打破它setTimeout()(尽管这并不完美,因为它可能会给用户带来一些闪烁)。

所以现在每次ResizeObserver loop limit exceeded出现在我们的 Sentry 中,我们都将其视为有用的提示,并尝试找出问题的原因。

于 2022-02-16T13:06:00.483 回答
0

赛普拉斯的一条线解决方案。使用以下命令编辑文件 support/commands.js:

Cypress.on(
  'uncaught:exception',
  (err) => !err.message.includes('ResizeObserver loop limit exceeded')
);
于 2022-03-03T23:03:13.123 回答