d3 / d3-transition

Animated transitions for D3 selections.
https://d3js.org/d3-transition
ISC License
224 stars 65 forks source link

Transition stuck when tab is not focus on Chrome and Safari #61

Closed ValentinH closed 7 years ago

ValentinH commented 7 years ago

I found an issue in Chrome when a transition is started in a tab that isn't focus. I could reproduce it on Chrome 54 on Ubuntu and OSX, Safari but not on Firefox.

Basically, the transition stay stuck in its initial state when I focus the tab (or the window in OSX) and can get unstuck after a while (not every time).

I don't have a JSFiddle yet to reproduce it but I'll try to create one. Just want to know for now if you have any ideas regarding this issue?

I noticed this issue after upgrading to v4 and couldn't reproduce it v3.

mbostock commented 7 years ago

I’d rather you post to bl.ocks.org (see https://bl.ocks.org/-/about) as JSFiddle wraps your code in frames that makes it hard to debug.

I can investigate this issue if you post an example, but my guess is that this isn’t a bug in D3. Time is (eventually) paused in background tabs, based on the discrepancy between the callback rate of setInterval and requestAnimationFrame. Thus, it is expected that a transition would pause while in the background. It’s also expected that the transition would resume when the page returns to the foreground, but depending on what else is going on, it’s possible you interrupted your transition which would prevent it from completing (and thus it might appear stuck, when it fact it was pre-empted by another transition).

In particular, you are strongly encouraged to use d3.interval and d3.timeout rather than setInterval and setTimeout, as d3.interval and d3.timeout use the same scheduling mechanism as d3.timer (and d3.transition), and hence will behave consistently in the background.

ValentinH commented 7 years ago

Can I use this http://blockbuilder.org ?

ValentinH commented 7 years ago

Thanks for the detailed answer. I'm actually using D3 with Angular where I also need some $timeout calls to synchronize the internal cycle. This is probably related to what you are explaining.

Indeed, I couldn't reproduce it in an example using D3 only.

ValentinH commented 7 years ago

I worked-around this by checking if the window is active before rendering the chart and deferring the rendering when the window becomes visible.

I don't know if it would be interesting to add a line in the documentation about this kind of problem when integrated in another framework. What do you think?