ResizeObserver - przekroczono limit pętli

143

Około dwa miesiące temu zaczęliśmy używać Rollbar do powiadamiania nas o różnych błędach w naszej aplikacji internetowej. Od tamtej pory pojawia się sporadyczny błąd:

ResizeObserver loop limit exceeded

To, co mnie w tym myli, to to, że nie używamy ResizeObserveri zbadałem jedyną wtyczkę, o której sądziłem, że może być winowajcą, a mianowicie:

Aurelia Resize

Ale wydaje się, że nie używa ResizeObserver.

Mylące jest również to, że te komunikaty o błędach pojawiają się od stycznia, ale ResizeObserverdopiero niedawno dodano obsługę do Chrome 65.

Wersje przeglądarek, które dają nam ten błąd to:

  • Chrome: 63.0.3239 (przekroczono limit pętli ResizeObserver)
  • Chrome: 64.0.3282 (przekroczono limit pętli ResizeObserver)
  • Edge: 14.14393 (SecurityError)
  • Edge: 15.15063 (SecurityError)

Więc zastanawiałem się, czy to może być błąd przeglądarki? A może błąd, z którym właściwie nie ma nic wspólnego ResizeObserver?

IOIIOOIO
źródło
2
Zabawne, jak mówią nawet lekarze ResizeObserver has a mechanism to avoid infinite callback loops and cyclic dependencies. Czy ostatnio zaktualizowałeś zależność do detektora zmiany rozmiaru elementu (zależność aurelia-resize)? Wygląda na to, że aktualizacja miała miejsce w styczniu…
Fred Kleuver
3
Aby obejść window.ResizeObserver = undefined;ten problem, na początku aplikacji możesz po prostu wyłączyć ResizeObserver. Nie jest najlepszym rozwiązaniem, oczywiście, ale po prostu przywraca go z powrotem do tego, co było, kiedy to działało ..
Fred Kleuver
1
Czy możesz dostarczyć kopię swojego kodu i tak, ResizeObserver daje UA możliwość (przy nieokreślonym limicie) zwolnienia za kaucją w pętli. Błąd zabezpieczeń krawędzi będzie zupełnie inny, ponieważ obecnie nie obsługujemy ResizeObserver.
gregwhitworth
1
@IOIIOOIO, rozważ dodanie własnej odpowiedzi odzwierciedlającej Twoją decyzję.
Alexander Taran
57
Ten błąd oznacza, że ​​ResizeObserver nie był w stanie dostarczyć wszystkich obserwacji w jednej klatce animacji. Jest to nieszkodliwe (Twoja witryna się nie zepsuje).
Aleksandar Totic

Odpowiedzi:

218

Możesz bezpiecznie zignorować ten błąd.

Jeden z autorów specyfikacji napisał w komentarzu do twojego pytania, ale nie jest to odpowiedź i nie jest jasne w komentarzu, że odpowiedź jest naprawdę najważniejsza w tym wątku i ta, która sprawiła, że ​​wygodnie ją zignorowałem nasze dzienniki Sentry.

Ten błąd oznacza, że ​​ResizeObserver nie był w stanie dostarczyć wszystkich obserwacji w jednej klatce animacji. Jest to nieszkodliwe (Twoja witryna się nie zepsuje). - Aleksandar Totic 15 kwietnia o 3:14

W repozytorium specyfikacji jest również kilka powiązanych kwestii .

Jacob Rask
źródło
Mieliśmy ten problem w pochodzeniu, z @microsoft/applicationinsights-webktórego nasz klient rejestruje błędy. Więc po prostu zignorować ten błąd poprzez utworzenie programu obsługi zdarzeń błędu przed applicationInsights i rozmowy stopImmediatePropagationipreventDefault
JohnnyFun
@JohnnyFun jakieś przemyślenia, jak to zrobić na safari? Nieważne, co otrzymuję tylko „błąd skryptu”. kiedy to się wydarzy
NSjonas
36

To stare pytanie, ale nadal może być pomocne dla kogoś. Możesz uniknąć tego błędu, zawijając wywołanie zwrotne requestAnimationFrame. Na przykład:

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
   });
});
Rani
źródło
3
czy stan jest potrzebny? "! Array.isArray (wpisy) ||! Wpisy.length"
Saeed Seyfi
Co masz na myśli?
Rani
1
Skąd wiedziałeś, żeby to zrobić ...?
ADJenks,
8

Jeśli używasz Cypressa i ten problem pojawia się, możesz bezpiecznie zignorować go w Cypress za pomocą następującego kodu w support / index.js lub 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
    }
})

Możesz śledzić dyskusję na ten temat tutaj . Ponieważ opiekun Cypressa sam zaproponował to rozwiązanie, uważam, że byłoby to bezpieczne.

Khateeb321
źródło
4

Mieliśmy ten sam problem. Okazało się, że winowajcą było rozszerzenie do Chrome. W szczególności rozszerzenie loom chrome powodowało błąd (lub jakąś interakcję naszego kodu z rozszerzeniem loom). Kiedy wyłączyliśmy rozszerzenie, nasza aplikacja działała.

Zalecałbym wyłączenie niektórych rozszerzeń / dodatków, aby sprawdzić, czy któreś z nich może przyczyniać się do błędu.

jross
źródło
1
Lub po prostu sprawdź w trybie incognito. Większość ludzi prawdopodobnie nie ma włączonych żadnych rozszerzeń lub znacznie mniej rozszerzeń w trybie incognito.
Jayant Bhawal
2

Dla użytkowników mokki:

Poniższy fragment kodu zastępuje okno.onerror hook instaluje się i zamienia błędy w ostrzeżenie. 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);
    }
  }
});

nie jestem pewien, czy istnieje lepszy sposób ..

Jan Kretschmer
źródło
1

dodaj odbicie jak

nowy ResizeObserver (_. debounce (wpisy => {}, 200);

naprawiłem ten błąd za mnie

Kreja
źródło