Suppose that we have a ticket sales site on which we want to show the price in document.title in order to increase user satisfaction and let them know that in which tab they have open (because we do not know whether place of departure / arrival, date, favorite carrier, and so on, and the price, by contrast, for different combinations is almost always different). At the same time, we know that, starting from version 56, Chrome has a policy of locking background tabs. What does this mean for this functionality?
According to the
documentation , rAF (requestAnimationFrame) is usually called 60 times per second. For screens that have a higher refresh rate, this value will also be higher (although you may not notice it with your eye).
Further it is written that if the tab is background and not active, the frequency may decrease, which is what happens, as we will see below.
Let's do an experiment. In the code under the spoiler, by requestAnimationFrame, the title is updated in the simplest way:
')
requestAnimationFrame page<!DOCTYPE> <html> <head> <script> requestAnimationFrame(function() { document.title += ' RAF' }); </script> <title>tab</title> </head> <body>tab</body> </html>
The result in chrome is as follows:
Yes, it should be so. Let's see what other browsers do:
IE11In order not to go to the settings and not to allow execution of scripts on local sites, we use the combination of the
http-server and
lt -p 8080 commands:

* Edge works in a similar way.
Firefox
where e10s is electrolysis
The result - only Firefox runs the rAF in the background tab. It would seem surprising that even IE11 does not perform rAF in the background, however,
Per the documentation, Chrome doesn’t call requestAnimationFrame () when a page is in the background. This behavior has been in place since 2011 . Since 2011, Karl !, which means that this behavior does not surprise anyone. Do not be surprised, even if music is playing in the background (via
<audio src="sound.mp3" autoplay></audio>
or whatever else), rAF, in the background, under any conditions, in any browser different from FF, will not be executed.
Therefore, answering the initial question "How to show the price in the title," the answer is quite simple - to show it not at the time of displaying the component, but at the time of receiving data from the API. The second solution would be to take away from the function that is used to animate the page when returning data from the API (a large loader on the whole screen is beautifully cleaned simply)), the initializer function. Unfortunately, it so happened that for some reason there are more than one such function, so this option entails large permutations and it was decided to abandon it. By the way, setTimeout / setInterval, are executed correctly, a third solution to the problem is possible through them.
In this story, you can finish and close, and now let's move on to what is actually happening, using the
source code requestAnimationFrame from WebKit :
int Document::requestAnimationFrame(Ref<RequestAnimationFrameCallback>&& callback) { if (!m_scriptedAnimationController) { #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) m_scriptedAnimationController = ScriptedAnimationController::create(*this, page() ? page()->chrome().displayID() : 0); #else m_scriptedAnimationController = ScriptedAnimationController::create(*this, 0); #endif
The first if is pretty straightforward, for details on
suspendScriptedAnimations and
setIsVisibleInternal .
In the second if, the value of the function
isLowPowerModeEnabled , each OS will be taken from different sources; in iOS, it is probably taken from
_didReceiveLowPowerModeChange .
The third if is most interesting;
topOrigin is just a top-level
SecurityOrigin document; the method itself is
here , in the comments in this method it is described in some detail what is happening in it. This method returns true if two scripts from different
origin can communicate with each other (read or write). At the same time, the user has a place to maneuver with NonInteractedCrossOriginFrame.
Thus, webkit browsers will acquire an rAF lock every time they enter one of the three if.
Let's go back to Firefox. We convert the original function that changes the page title to the following:
Change the title for each animationFrame requestAnimationFrame(function handler() { document.title += 'R' requestAnimationFrame(handler); });
As you can see, everything happens a bit differently in
Firefox / Gecko than in webkit. If you find the implementation of
request_animation_frame , then you will notice that:
- // TODO: Should tick animation only when document is visible - which means that someday the behavior will correspond to the behavior of other browsers, so what is happening now, you can not particularly get hung up.
- There is is_faking_animation_frames where it turns out that the guys from Gecko, in case you have a lot of fake animations, throw you on FakeRequestAnimationFrameCallback.
I do not even know who is cooler.
Good links: