Closed Bug 667236 Opened 13 years ago Closed 13 years ago

change in setInterval's timers on blurred tabs causes undesirable effect

Categories

(Core :: DOM: Core & HTML, defect)

All
Windows 7
defect
Not set
major

Tracking

()

RESOLVED INVALID

People

(Reporter: gvillafu_soad15, Unassigned)

References

()

Details

User-Agent:       Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
Build Identifier: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0

when a tab loses focus all timers are changed to 1000ms. in the sample page, this produces the gallery that uses setInterval function changes the active image considerably fast, because of this change

Reproducible: Always

Steps to Reproduce:
1. load the sample page
2. blur the tab and wait for a while (1 min or 2)
3. focus the tab and you will see the problem

Actual Results:  
all events programmed with setInterval on major intervals (when the pages recovers focus) suddenly are called in 1000ms intervals, which produce an undesirable effect, in this case, in my website's main gallery

Expected Results:  
all timers below than 1000ms must be reduced, but all others must be left in the same circumstances, otherwise you'll make the browser load more CPU & memory than needed in these timers

also chrome (since 12 to right now [14]) has this bug, and had it before than firefox does (in 5th version, since alphas).

other website (www.colegiovasconcelos.edu.mx/website/principal.html) has the same problem because i helped to do galleries in this webpage as well.
Component: General → DOM: Events
Product: Firefox → Core
QA Contact: general → events
Component: DOM: Events → DOM
QA Contact: events → general
> when a tab loses focus all timers are changed to 1000ms. 

No, only timers set for less than 1000ms are changed to 1000ms.

What makes you think that your 15000ms timer is being changed to 1000ms?

> also chrome (since 12 to right now [14]) has this bug

Chrome implements the same algorithm we do: timers for less than 1000ms are changed to 1000ms, while ones for longer than 1000ms are unchanged.
Blocks: 633421
Build: Mozilla/5.0 (Windows NT 6.1; rv:7.0a1) Gecko/20110626 Firefox/7.0a1

I could not reproduce the issue. I get the following message:
"You are seeing this page because the system administrator of 000webhost.com is currently checking this website for malicious content."
> No, only timers set for less than 1000ms are changed to 1000ms.

Well, maybe, but the problem here is that it seems like all the events that should've passed when the tab was in background are triggered when the tab is in foreground again.
 
> I could not reproduce the issue. I get the following message:
> "You are seeing this page because the system administrator of 000webhost.com
> is currently checking this website for malicious content."

I know, my website was under review from 7:00 to 14:00 UTC -5. Right now is available again.

Maybe you have to wait like 5-10 mins to see the issue.
> it seems like all the events that should've passed when the tab was in
> background are triggered when the tab is in foreground again.

We certainly don't do that.

Do you see the issue if you don't use jQuery's animation facilities?  It's possible that jQuery is doing something weird.
> We certainly don't do that.

> Do you see the issue if you don't use jQuery's animation facilities?  It's
> possible that jQuery is doing something weird.

sorry, i just checked the jQuery's documentation and says: "you should never queue animations using a setInterval or setTimeout loop. [...] browsers that support requestAnimationFrame will not update animations when the window/tab is not displayed. If you continue to queue animations via setInterval or setTimeout while animation is paused, all of the queued animations will begin playing when the window/tab regains focus. [...]"

so, i'll close the bug, thanks!
Status: UNCONFIRMED → RESOLVED
Closed: 13 years ago
Resolution: --- → INVALID
Thank you for double-checking that!

It sounds like the real issue you were running into wasn't the setTimeout clamp then but the exponential backoff on the refresh driver in background tabs....
Blocks: 614733
No longer blocks: 633421
To be honest, I don't know what you really mean with that bug, but... have you checked the issue I was trying to report?
Yeah, I can reproduce the problem you were trying to report, given comment 5.  It is indeed due to requestAnimationFrame animations running very slowly in background tabs after some point.
I'm a chinese developer and it's difficult to be here to visit this website.cause the government takes measures to block us.unfortunately, I encountered this trouble as well,but I resolved this problem at the end.
In fact, the reason that caused this issue may be a little complex , but you can handle it by a very easy way.
you may have some code in your project like this :

var o = {
 tick : function{ 
    var timerId =  window.setInterval(function(){
	slidPlayer.moveOut();
        slidPlayer.changeBigShow();
	slidPlayer.fly();				
      },2000);
  }
}

so the trouble will happen when you lost the focus on this page that contains the
code and when you return back the bug has been created. The simple way to handle this :
1.bind handler on the window object for "blur" event or somekind of that represent  you have left this page. And you can invoke clearInterval() to stop animations.

2.bind handler on the window object for "onfocus" event or somekind of that represent you have come back to this page. And you can invoke tick() to start animations.And the final code should be like this:

var o = {
 cons : timerId ,
 tick : function{ 
   this.timerId =  window.setInterval(function(){
	slidPlayer.moveOut();
        slidPlayer.changeBigShow();
	slidPlayer.fly();				
      },2000);
  },
  start : function(){
     this.tick();
  },

  stop : function(){
       clearInterval(this.timerId);
  }
}

window.onfocus = function(){
   o.start();
};
	
window.onblur = function(){
   o.stop();
};

I think it will work smoothly and good luck.
Thanks for the info, wang.huan
But I solved the problem by my own like a month ago.
This is my code:

getUA = function() {        //This function checks the browser you're using
	var ua = navigator.userAgent;
	if (ua.indexOf("Firefox/") != -1) return 2;
	if (ua.indexOf("Chrome/") != -1) return 3;
	else { return 4 }
};

rotate = function(){        //This function is set every 20000 ms to switch slides
    var triggerID = $active.attr("rel") - 1;
    var image_reelPosition = triggerID * imageWidth;

    $(".paging a").removeClass('active');
    $active.addClass('active');

   if ((document.hasFocus() && getUA() == 2) || (!document.webkitHidden && getUA() == 3)) $(".image_reel").animate({left: -image_reelPosition}, 300);
   else { $(".image_reel").css({left: -image_reelPosition}) }

}; 

We check the browser's user agent, and then, perform the animation if document.hasFocus() (on Firefox) or if !(document.webkitHidden) (experimental function in Chrome).

If I don't get that expected results, animation isn't performed but the content is moved anyway. (I don't use the same function in Chrome because hasFocus() in that browser returns *true* regardless the focus status of the tab/window).

Again, thanks for your contribution.
> if (ua.indexOf("Firefox/") != -1) return 2;

That's completely broken for non-Firefox Gecko UAs.  If you're going to UA-sniff, at least do it correctly.....
And better than UA-sniffing would be using object-detection on the visibility API.
OK, I know this code excludes a lot of browsers based on the same components than Firefox and Chrome, but this is only a temporal solution. Do you think it's better UA-sniff with "Gecko" and "WebKit"?
It's better to do comment 12, but yes sniffing "Gecko" would make more sense than sniffing "Firefox".

I can't speak to "WebKit", since different WebKit forks have different behavior here.
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.