question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Blank Carousel when looping with 2 slides (inactive browser tab)

See original GitHub issue

Hello,

when trying to create an automated slideshow with two slides and loop: true, I stumbled upon an interesting edge case. I used setInterval() to call scrollNext() every few seconds. After I switched tabs and came back later (one or two minutes is enough), the embla carousel was blank and the source code had a weird transform value:

<div class="embla__container" style="transform: translate3d(-5.72608e+10%, 0px, 0px);">

It can be reproduced here: https://codesandbox.io/s/embla-carousel-align-start-vllyp

I think this only happens in quite specific conditions - e.g. I was only able to reproduce this with two slides. I worked around the problem by using the Page Visibility API and only calling scrollNext() if the page is visible, but I thought it might be worth reporting the issue.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

4reactions
davidjerlekecommented, Oct 27, 2019

Hello Gerhard (@niubsta),

I’ve done some digging and I know why this is happening. My initial hunch was kinda right, the setInterval() timer is clashing with requestAnimationFrame().

Why this is happening at all

Basically, what’s happening is that as soon as the browser tab is blurred, Embla stops doing visual updates because requestAnimationFrame() is designed to not run on an inactive browser tab. This makes sense because it saves processing power and battery by preventing expensive rendering from taking place when a tab is blurred. BUT, as you can see in the screenshot below, setInterval() is running even though the tab is inactive and calling scrollNext() repeatedly.

Embla resets the targetVector inside the visual render loop, and it must happen here in order to create the seamless infinite effect. But as already mentioned, the render loop is paused when the browser tab is blurred which means that nothing is stopping targetVector from growing out of hand when scrollNext() is called by setInterval().

console

Why this is happening with 2 slides only

Embla uses a specific approach to cover an edge case when the carousel only has 2 slides. When it has more than 2 slides, both scrollPrev() and scrollNext() will find the targetVector (to which position the carousel should scroll) by looking for the shortest route possible. scrollNext() will in this case always move forward because the shortest route from i.e. slide index 0 to 1 is forward. This is because a backward movement to index 1 would have to scroll by all slides from the last index down to 1, causing this route to be longer. BUT, when the carousel only has 2 slides, the shortest route from slide index 0 to 1 could actually be backward, even though scrollNext() is called!

This can be confusing because scrollNext() is expected to always move forward, and scrollPrev() backward. This is why Embla only adds to the targetVector when it has 2 slides. In contrast, when it has more than 2 slides, it will compare all possible routes and choose the smallest possible targetVector which prevents targetVector from growing out of hand.

Conclusion

I hope I’ve managed to explain why this happens 😅. I’m gonna argue that this isn’t a bug. Maybe we should ask the question: Why should we run autoplay for a carousel when the browser tab is blurred? But the main reason is that at the time of writing autoplay isn’t a native feature of Embla Carousel and I’m going to leave the implementation up to the user. There’s a couple of ways to avoid the issue you describe. Below are two different ways:

I hope that this makes sense? Anyways, I’m very happy for your contributions and clear demonstrations! Thank you very much for reporting this and don’t hesitate to do it again. I’ve added you as a contributor 🎉.

Best, David

2reactions
gerhard-lechnercommented, Oct 28, 2019

Hello @davidcetinkaya ,

first of all - kudos for the extraordinarily detailed explanation! 😃

I was a bit confused when you explained that when using scrollNext() with two slides the animation actually goes backwards. This isn’t the case in the example code in my initial post. The animation always goes forward, which is because of loop: true.

So may I ask: Is there a reason why you use loop: false in your AutoPlay code and then

if (embla.selectedScrollSnap() === lastIndex) {
  embla.scrollTo(0);
} else {
  embla.scrollNext();
}

instead of just using scrollNext() with loop: true?

Considering the issue itself: Your solution with using requestAnimationFrame is without a doubt a much cleaner approach than being sloppy and just using setInterval() like I did in the first place.

So I don’t think it is necessary to actually try to fix this issue. However, I would suggest adding a CodeSandbox section as you’ve mentioned before, to make sure everyone interested in using Embla carousel for a slideshow gets pointed in the right direction concerning a proper implementation.

Does this make sense to you?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Blank Carousel when looping with 2 slides (inactive browser ...
Hello, when trying to create an automated slideshow with two slides and loop: true, I stumbled upon an interesting edge case.
Read more >
Carousel · Bootstrap v5.0
A slideshow component for cycling through elements—images or slides of ... (such as when the browser tab is inactive, the browser window is...
Read more >
Blank frame/item in Owl Carousel 2 loop - Stack Overflow
I am using owl carousel 2 on home page of https://staging.thomasfarms.kitchen/ to show four slides. The loop option is set to true.
Read more >
Carousel | Components - BootstrapVue
When using img-src or img-blank on <b-carousel-slide> , you can set the image ... as when the browser tab is inactive, the browser...
Read more >
Module General Settings - Slider Revolution
Automatically change to the next slide when the user switches to another tab/window and then comes back to the page. 2. Disable Blur/Focus...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found