[Bug]: reInit() is called synchronously inside ResizeObserver callback
Which variants of Embla Carousel are you using?
- embla-carousel (Core)
- embla-carousel-react
- embla-carousel-vue
- embla-carousel-svelte
- embla-carousel-autoplay
- embla-carousel-auto-scroll
- embla-carousel-solid
- embla-carousel-auto-height
- embla-carousel-class-names
- embla-carousel-fade
- embla-carousel-website (Documentation)
Steps to reproduce
- Create a standalone HTML page that uses
[email protected]only, without any application code around it. - Render a basic Embla carousel inside a wrapper element whose width can be toggled between two values, for example
1000pxand520px. - Wrap
window.ResizeObserverso you can track when its callback is active. - Patch
emblaApi.reInit()so you can count how many times it runs while theResizeObservercallback is still active. - Toggle the wrapper width several times.
- Log the counters.
In my isolated repro, the result is:
{
"roCallbacks": 13,
"reInitCalls": 6,
"reInitInsideRO": 6
}So Embla calls reInit() synchronously while the ResizeObserver callback is still running.
I then repeated the same repro with a custom watchResize override:
watchResize: (emblaApi) => {
requestAnimationFrame(() => emblaApi.reInit())
return false
}That produced:
{
"roCallbacks": 58,
"reInitCalls": 58,
"reInitInsideRO": 0
}So deferring reInit() removes the problematic condition.
Expected Behavior
Embla should avoid calling reInit() synchronously from inside the ResizeObserver callback.
The resize handling should move the reInit() work out of the observer callback, for example by deferring it with requestAnimationFrame, so responsive layouts do not hit ResizeObserver loop warnings.
Additional Context
I isolated this outside my app in a standalone Embla-only page, so this does not appear to depend on framework integration or application-specific code.
The reason I’m reporting this as a library bug is that the current source still appears to call reInit() directly from the default resize path:
This also looks related to the earlier ResizeObserver fix in:
- https://github.com/davidjerleke/embla-carousel/issues/488
- https://github.com/davidjerleke/embla-carousel/pull/493
That earlier fix deferred resize-triggered reInit() with requestAnimationFrame, which matches what I see in the isolated repro: once reInit() is deferred, it no longer runs inside the ResizeObserver callback.
The browser warning itself may be timing-sensitive, but the underlying behaviour is deterministic and verifiable: in the standalone repro, reInit() is called from inside the active ResizeObserver callback with default Embla behaviour, and no longer is once reInit() is deferred.
What browsers are you seeing the problem on?
Chrome
Version
v8.6.0
CodeSandbox
https://codesandbox.io/p/sandbox/pvz25r
Before submitting
- I've made research efforts and searched the documentation
- I've searched for existing issues
- I agree to follow this project's Contributing Guidelines for bug reports
Source: davidjerleke/embla-carousel