From a490f9b390ef415b69e359affd5eee211aa1b887 Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Wed, 9 Feb 2022 10:35:10 +0100 Subject: [PATCH] fix(core): wrap resize observer callback in requestAnimationFrame Fast browser window resize produces `Error: ResizeObserver loop limit exceeded`. The error isn't visible in browser console, doesn't affect functionality, but degrades performance of slider. Solution is taken from https://stackoverflow.com/a/58701523/17278571. Fixes #5440 --- src/core/modules/resize/resize.js | 34 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/core/modules/resize/resize.js b/src/core/modules/resize/resize.js index 8b27b14bd..b1f359054 100644 --- a/src/core/modules/resize/resize.js +++ b/src/core/modules/resize/resize.js @@ -3,6 +3,7 @@ import { getWindow } from 'ssr-window'; export default function Resize({ swiper, on, emit }) { const window = getWindow(); let observer = null; + let animationFrame = null; const resizeHandler = () => { if (!swiper || swiper.destroyed || !swiper.initialized) return; @@ -13,26 +14,31 @@ export default function Resize({ swiper, on, emit }) { const createObserver = () => { if (!swiper || swiper.destroyed || !swiper.initialized) return; observer = new ResizeObserver((entries) => { - const { width, height } = swiper; - let newWidth = width; - let newHeight = height; - entries.forEach(({ contentBoxSize, contentRect, target }) => { - if (target && target !== swiper.el) return; - newWidth = contentRect - ? contentRect.width - : (contentBoxSize[0] || contentBoxSize).inlineSize; - newHeight = contentRect - ? contentRect.height - : (contentBoxSize[0] || contentBoxSize).blockSize; + animationFrame = window.requestAnimationFrame(() => { + const { width, height } = swiper; + let newWidth = width; + let newHeight = height; + entries.forEach(({ contentBoxSize, contentRect, target }) => { + if (target && target !== swiper.el) return; + newWidth = contentRect + ? contentRect.width + : (contentBoxSize[0] || contentBoxSize).inlineSize; + newHeight = contentRect + ? contentRect.height + : (contentBoxSize[0] || contentBoxSize).blockSize; + }); + if (newWidth !== width || newHeight !== height) { + resizeHandler(); + } }); - if (newWidth !== width || newHeight !== height) { - resizeHandler(); - } }); observer.observe(swiper.el); }; const removeObserver = () => { + if (animationFrame) { + window.cancelAnimationFrame(animationFrame); + } if (observer && observer.unobserve && swiper.el) { observer.unobserve(swiper.el); observer = null;