requestAnimationFrame - Tell when browser loses focus - javascript

From what I have read requestAnimationFrame can tell when the browser loses focus. Is there some kind of event that fires when this occurs? I'm looking to pause and resume code in connection with requestAnimationFrame.

requestAnimationFrame is not an element on which an event can be or is fired when the browser loses focus; it just sets up a callback. But standard behavior is that when the browser/tab goes out of focus, callbacks are paused. Therefore, most likely your code (if in a callback) is already being paused.
There is a possibility that all browsers may not pause callbacks, but instead slow them down. However, the W3C spec would seem to imply pausing, not slowing:
Whenever a Document's hidden attribute ([Page Visibility]) is false and the animation frame request callback list is not empty, the user agent MUST regularly queue a task...
If d's hidden attribute is true, continue to the next entry in the contexts list.
If you want to be absolutely sure your code is pausing when the tab is out-of-focus, or if the code you are trying to pause is not structured as part of a RAF callback, then you could consider using the
Page Visibility API.
Note that both RAF and Page Visibility API are available only in IE>=10.

Related

Stop window from loading after hyperlink click

Some of the queries we have can take tens of seconds to complete.
I would like to be able to cancel the page-load as if the "Stop" button from browser was pressed.
But binding it to key shortcuts using javascript.
From extensive testing it seems that window.stop() works only when the document is not ready or still loading. I would like to stop the page from loading after a link was clicked.
The goal of doing it using javascript is that I would like to perform other operations too.
Tested in Chrome, FF dev and IE...
Anyone encountered a similar behavior and have suggestions on how to proceed ?
1- user clicks a link/a/href
2- realizes its the wrong link
3- presses ctrl-c to stop the loading and stay on this page
the function checks for certain conditions before proceeding to not prevent default behavior...
TLDR: when calling window.close() after click a link/a it wont stop the page from loading, is there any other way to stop a page from loading after a href click event
It turns out that you cannot use this method the way I needed too.
The stop() method is exactly equivalent to clicking the stop button in
the browser. Because of the order in which scripts are loaded, the
stop() method cannot stop the document in which it is contained from
loading, but it will stop the loading of large images, new windows,
and other objects whose loading is deferred.
source / developer.mozilla.org

Deferred long-running timer task(s) to improve scrolling smoothness

I was inspecting my page and I got this warning:
Deferred long-running timer task(s) to improve scrolling smoothness. See crbug.com/574343
I've also seen:
Blink deferred a task in order to make scrolling smoother. Your timer tasks should take less than 50ms to run to avoid this. Please see https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-performance/rail and https://crbug.com/574343#c40 for more information.
What is this?
This occurs when Blink (Chrome's rendering engine) decides to delay executing a timer (like a function passed to requestAnimationFrame, setTimeout, or setInterval) because those functions are generally taking >50ms to execute and there is user touch input. It's done to prioritize handling user input (like scrolls and taps) above what the site is doing.
If you've encountered this message, then its likely your users will get similar behavior. Here's how to reproduce this scenario:
Have long-running javascript that is triggered via timers
Be on mobile (or emulating it with DevTools device mode)
Have touch input, scrolling with finger down on the screen is the most reliable. Tapping or flinging the page may also trigger it, but it is less likely and harder to reproduce.
The devtools' experimental CPU throttling will make the JS take longer and give you a better chance of seeing it.
The method for how to solve this is directly from the referenced issue in the console message down in comment 40:
Record a timeline on the page that is triggering the console message about deferral.
Select the entire timeline and open the "Event Log" pane near the bottom of the window.
Enter "Timer Fired" into the filter text field. (See image at bottom)
Look for timers in the list whose "Total Time" exceeds 50 milliseconds. These are the problematic ones. (Note that timers that exceed 10 milliseconds can also trigger this message in some cases where the browser is processing a user gesture. )
You want these functions to execute faster or less frequently.

Why does 'stay on page' dialog pauses asynchronous function?

So this is really bugging me, I don't know if it is a browser related glitch or javascript just works that way ( I hope it does). I created a fiddle. https://jsbin.com/laluziqede/1/edit?html,js,output
Open your console, then click the button. When the dialog appears the function continues normally (first console.log isn't paused), however the one inside setTimeout function is paused and will only show after you click 'stay on page'.
But why, could someone explain this? I want to use this property in my application (execute an action right after user clicks stay), but I'm not sure if it's a good practice and is it working on all browsers and devices.
Edit: Here's the code from the bin:
$(window).on('beforeunload', function() {
return 'Check your console please and then click stay';
});
$('#click-me').on('click', function() {
window.location.href='about:blank';
console.log ('dialog won\'t stop me from showing');
var timer=setTimeout(function() {
console.log('this was paused by the dialog');
},0);
});
The behaviour is browser dependent. I tested it in Firefox, Chrome, IE and Edge, and of those only Chrome has the behaviour that you describe.
The difference lies either in when the beforeunload event is triggered, or when it is handled. Most browsers trigger the event immediately when you change the location property and also handle it immediately. Chrome either triggers and handles the event when the navigation is actually about to happen, or places the event on the queue and handles it later just like regular events.
In Chrome the code inside the setTimeout handler will not happen until after the beforeunload event is handled, either because the navigation is handled before any queued events, or because the timout event is after the unload event in the queue.
Javascript is single threaded (unless you start using things like WebWorkers and other newer technologies). So the timer function schedules something to be done, but it will only be done when everything else has yielded control of the javascript thread. So timer is only asynchronous in the sense that you're asking for some work to be done after some period of time, but it is not truely asynchronous in the sense that that something can be done while something else is also being done.
This applies to things like XHR requests as well, even though the XHR request are indeed dispatched asynchronously, the responses are all handled synchronously one at a time.
Your specific example is a bit odd in that it's not another javascript function that is blocking, it's a browser security feature that is making sure you want to let the previous javascript operation take you away from the current page. The concept is the same though.

DOM onUnload doesn't fire until response begins

Consider the following code:
$(window).unload(function () {
console.log('foo');
});
If I trigger the unload event by navigating to a different URL, the event doesn't fire until the browser begins to get a response.
i.e. if the DNS lookup takes a long time, or the remote server takes time to respond (the loader animating anti-clockwise in Firefox, the event only fires once it starts rotating clockwise)
Is there another event I can listen to that happens as soon as navigation begins?
I realise I could attach to link clicks and intercept there, but that's just going to be hacky because there countless edge cases I'd have to manually capture here. OnUnload is the sensible place, but it doesn't behave as I want :(
thoughts?
There's window.onbeforeunload that might do what you're looking for.

HTML page unload is not getting called always in IE

I have an onunload method written on the body of a form. Since the page got large amount contents to be streamed from the server,it takes a while to download the entire form. While the form gets downloaded to the browser,if the user clicks the window close button, the unload event (written to call a server side action to reset some flag) is not getting triggered sometimes. The unload method is written towards the end of the page, is that a reason for this? Is there anyway by which we can make sure that onunload is guaranteed to be called?
The thing that hits you is probably the fact that IE doesn't fire an unload event if window.onload hasn't fired yet. The solution is described in this blog post: http://blog.moxiecode.com/2008/04/08/unload-event-never-fires-in-ie/
There are two reasons. One, like you said, the browser may not even be reaching the unload, so you should declare it above your body tag.
The other is that, as GoldenNewby already stated, you need to give the code some time to finish, such as an alert. This is because the JavaScript is cleared from memory the moment the next page is ready, and execution is simply stopped on the old script. If you can guarantee the script will take less time than a page load, you won't need an alert, but if it could take more than 2ms or so to execute, you will need to buy some time.
IE has an onbeforeunload event, you can use that instead. Just set a flag so that your onunload can exit early if onbeforeunload already did its thing.
window.onunload = window.onbeforeunload = function () {
if (window.isAlreadyUnloaded) return;
window.isAlreadyUnloaded = true;
// do your stuff here.
}

Categories