Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should pending idle callbacks in the queue be run when the page is unloaded/backgrounded? #73

Closed
philipwalton opened this issue Jul 25, 2018 · 5 comments

Comments

Projects
None yet
5 participants
@philipwalton
Copy link
Member

commented Jul 25, 2018

Analytics and measurement code is a great use case for requestIdleCallback(), but there are a small set of situations in which you wouldn't want to use requestIdleCallback() for fear that the callback would never run. Some example of this are:

  • Sending end-of-session data (as the page is being unloaded)
  • Tracking outbound link clicks (which also happens as the page is being unloaded)
  • Tracking visibility state changes (which sometimes happen as the page is being unloaded)

Because some analytics tracking functions need to be run urgently, most analytics libraries just run all their analytics code synchronously because they don't know how the page author is going to use their library.

If requestIdleCallback() could provide some sort of guarantee that a callback will be run before a page is unloaded, put into bfcache, or the user switches tabs/apps, then I think all analytics vendors would switch to using it when available, in all situations.

That seems like a big win to me. Thoughts?

@tdresser

This comment has been minimized.

Copy link

commented Jul 26, 2018

@rmcilroy

This comment has been minimized.

Copy link
Contributor

commented Aug 1, 2018

There was some discussion on this idea in #3. The consensus was that it is possible to achieve this by having logic in an onunload / onbeforeunload handler to check whether the task has been run, and if not perform the operation. Given that setTimeout and similar callback mechanisms don't have an option to guarantee they will be executed either, we decided to be consistent with them and avoid adding complexity to the API.

@spanicker

This comment has been minimized.

Copy link

commented Aug 2, 2018

@philipwalton - could you elaborate on why lifecycle events (pagevisibility, freeze and even unload) don't suffice? The analytics library would have code for steadystate and also hooking into these handlers.

@philipwalton

This comment has been minimized.

Copy link
Member Author

commented Aug 7, 2018

@spanicker lifecycle events do suffice (and it's what I ended up doing for my case), it's just non-trivial to wire it all up yourself. It's also really easy to get wrong since there are a lot of browser inconsistencies in this space (e.g. the hoops I had to jump through here in the PageLifecycle.js).

Furthermore, it's not the case that a developer can just simply run the queued callbacks in a visibilitychange/freeze/unload handler because that will mean the callbacks may be executed out of order (e.g. if any of the requestIdleCallback() callbacks enqueue more callbacks), so the only want to handle this in an unload situation is to use microtasks, which may require additional polyfills depending on the browser support needed.

It's definitely possible to do it yourself, it's not not super easy to do right. I imagine most analytics libraries would rather just run the code sync to ensure it happens rather than deal with the challenges of doing it right (and that's unfortunate).

I may do a blog post or something advocating the right way to do this.

@yoavweiss yoavweiss added the triage label Oct 17, 2018

@philipwalton

This comment has been minimized.

Copy link
Member Author

commented Oct 17, 2018

I wrote up my experience handling this issue in a blog post:
https://philipwalton.com/articles/idle-until-urgent/

I think we can close this for now, since realistically developers would still need to handle this themselves until all rIC implementations were the same. Also, @spanicker has a proposal for a high-level scheduling API, and that's probably a better place to address this type of concern anyway.

@philipwalton philipwalton removed the triage label Oct 17, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.