Monday, January 23, 2017

Chrome 56 Will Aggressively Throttle Background Tabs

[Jan 26, 7:25am]: Google has responded to this article and the plans for throttling:
Unfortunately, our current implementation throttles WebSockets. Because of this we ARE NOT SHIPPING this intervention in M56.
The current plan is to disable time-budget background timer throttling for the pages with active connection (websocket, webrtc and server-sent events) and to ship in M57 (subject to further feedback). We will keep you updated with the progress.

----------------

"L'enfer est plein de bonnes volontés ou désirs"

Chrome 56 introduces a commendable optimization to throttle background tabs' timers. From the Intent to Implement, the gist is:


  • Each WebView has a budget (in seconds) for running timers in background.
  • A timer task is only allowed to run when the budget is non-negative.
  • After a timer has executed, its run time is subtracted from the budget.
  • The budget regenerates with time (at rate of 0.01 seconds per second).

This is generally a Good Thing. Browser vendors should be concerned about battery life, and this will do a lot to help. Unfortunately, this implementation is ignoring the new reality: the browser is no longer just a reading device; it is the world's largest application platform.

This will break apps on the web.

When idle, your application's timers may be delayed for minutes. Aside from terrible hacks like playing zero-volume sounds, you have no control over this. Avoiding expensive CPU work is not a panacea; that some applications must do significant work in the background, including syncing data, reading delta streams, and massaging said data to determine whether or not to alert the user.

Worse yet, the heuristic is based on local CPU time; faster clients may have no issue and face no throttling, but slower devices often will, causing cascading processing and notification delays.

Popular applications like Slack and Discord, as well as our own application (BitMEX, a Bitcoin trading site) will be hugely and adversely affected by this. What good is the user granting the Notification permission if we can't do the processing necessary to even fire the notifications?

Before you think this sounds alarmist, here's real data from a few days ago, where I ran a simple `setInterval` every second while our application ran and recorded the actual time elapsed. This shows timer delays on a site that does a medium amount of background processing:


Gone are the days when you could count on timers to fire semi-reliably.

This has dire ramifications for sites that keep WebSocket subscriptions open. In fact, we've already begun work with Primus to remove client-side heartbeat timers which will make it into a new semver-major soon. Emulation libraries like socket.io may have more trouble.

The recommendation from the Chrome team is to move this work to Service Workers. While it's great to have a way out, this recommendation involves significant compromises, development work, and compatibility fallbacks. And who's to say that Chrome won't have to start throttling noisy Service Workers in the future?

If you run an application that counts on background timers firing reliably, please leave a respectful comment explaining your use case in the Intent to Ship thread before this rolls to Stable. The team is listening and has already acknowledged their intent to make this throttling less aggressive. More data points would be very useful to them to ensure Chrome 56 does not break the web.

49 comments:

  1. did you just do a setInterval with printing current time ? If so the 'budget' mechanism is not really working is it ? otherwise a simple lower priority / less cpu based on device capabilities etc would be acceptable to me

    ReplyDelete
    Replies
    1. No - this was a setInterval running at the same time as the regular work my existing production application does. So it's a good representation of what timers on a typical SPA might be throttled to.

      Delete
  2. RIP cookie-clicker and cookie-clicker-alikes. And that loligater game.

    ReplyDelete
  3. I am worry about apps like soundcloud or spotify (web versions) that will die and stop playing or making big pauses between songs.

    Will make sense to show a pop up (requested manually by the app) to ask for "run on background" permission?

    ReplyDelete
    Replies
    1. That shouldn't be a problem as apparently "tabs with audio are always considered foregrounded". Source: https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/-dmrNAFHd-4/discussion

      Delete
    2. And there's your workaround. Loop a 1 second null audio file for as long as you need to (please don't).

      Delete
    3. help! How do I record silence? Do I need to update my microphone to capture silence?

      Delete
    4. I'd send you the answer, but I'm all out of paper...can you fax me a few blank sheets?

      Delete
    5. The Chrome team has confirmed that this will not work; the mechanism for disabling throttling will be the same as the one that shows the speaker icon in the tab. That icon does not show with inaudible sound.

      Delete
  4. Will make sense to show a pop up (requested manually by the app) to ask for "run on background" permission? +1

    ReplyDelete
    Replies
    1. Yes please, at least give us this option so users can give this permission and keep a tab running smoothly, we run a dedicated app that control certain things on our clients companies, they keep it in the background and run their PoS software on another tab, if the app is throttled they will notice and it's going to mess things up.

      Please give us the choice as permission or a configuration option to disable throttling.

      Delete
  5. How will I mine bitcoin in the ads I serve???

    ReplyDelete
    Replies
    1. you have to target firefox users only.

      Delete
  6. I used to encounter this problem before Chrome 56, but it is not the browser fault, it might the code you wrote for timer would delay, there is some way to break through and get a correct time.

    ReplyDelete
    Replies
    1. That is a different issue; the behavior in Chrome 56 is brand-new.

      Delete
  7. As a developer I hate the current slowdown already... And as a user I have no problem with having 81 Tabs open (current status)...

    If they would really care about performance they would ship an ad-blocker by default :D :D

    Btw. I am really worried about the extensive use of serviceworkers. Not that I would not find them useful, but somehow I have a feeling that the tracking industry will find them even more useful.

    ReplyDelete
  8. Sadly the well was poisoned by lazy developers who used by CPU and battery for non-essential tasks. It's just not sustainable for every tab to have free access to my computer's limited resources.

    ReplyDelete
  9. This seems like a good idea, but I'm concerned it'll completely destroy my ability to cast a tab to a Chromecast while doing other work in a foreground tab. Should I be concerned?

    ReplyDelete
    Replies
    1. No. The system is aware of tabs that are playing audio or the source of mirroring, and this factors into the foreground vs. background state of the tab.

      Delete
  10. They really ought to just include a JS function that disables this or something.

    ReplyDelete
  11. I have an app that allows a client tab to sync audio playback with a host video tab through socket.io. This'll kill that =/

    ReplyDelete
  12. the great suspender chrome extension (which supports whitelisting) is a better approach

    ReplyDelete
  13. Most of the timers on background tabs on my browser are only working to serve ad rotations. Google's approach may be over aggressive - I think I would have chosen to allow the user to opt-in to timers on a specific tab - but given the aggressive ad serving on some sites I can see why they would choose to do this.

    ReplyDelete
    Replies
    1. Except for the thousands of internal web apps that rely on chrome running smooth... chrome isn't only for reading websites anymore, there are a lot of companies that built their software for the web, I'm not against this but there should be a way to disable it from the options so it can be turned off in a corporate office.

      Delete
  14. Even in backgrounded tabs, messages from web workers and incoming messages on websockets are processed as they happen, so there is an opportunity to take some action on these events. For websockets, a ping-pong protocol driven by the server should work just fine.

    We've had issues with timer in backgrounded tab for a while now, and we've been using HackTimer to help restore reliability for our important timers: https://github.com/turuslan/HackTimer (there was a memory leak in HackTimer when we started using it, but we fixed it in our copy, and I assume it's been fixed upstream too by now).

    ReplyDelete
    Replies
    1. As it turns out (at least in the current implementation), this is not true. See https://groups.google.com/a/chromium.org/d/msg/blink-dev/XRqy8mIOWps/Ctq56g4VBQAJ

      Delete
    2. Thanks for the clarification Sam. In that case, the proposal is quite terrible for real-time apps that get backgrounded. Am glad they're revisiting this and delaying shipping.

      Delete
  15. This comment has been removed by the author.

    ReplyDelete
  16. What if something like a QOS tag were established for the page author to declare their need for a higher priority? The browser would also need to display an icon on tabs that have requested higher priority so that users can close sites that are abusing the privilege.

    ReplyDelete
  17. I'm using https://github.com/deanoemcke/thegreatsuspender by long time and is perfect.

    ReplyDelete
  18. Are Service Workers the only way out ? What about regular or shared Workers ?

    ReplyDelete
    Replies
    1. also, are Desktop browsers not running on batteries affected too? We have some polling to keep sessions alive on regular Desktop platforms, we need some predictable reliability (or whatever is close to that). Thanks for any sort of extra clarification.

      Delete
  19. Is it just Chrome, or also Chromium?

    ReplyDelete
  20. Slack or discord are using websockets. It's fucking 2017, stop using setTimeout/setInterval as part of realtime communication protocol.

    Also it will not break the internet. It will break only shitty pages with lots of non async code.

    ReplyDelete
    Replies
    1. "Emulation libraries like socket.io may have more trouble."

      Delete
    2. This comment has been removed by a blog administrator.

      Delete
    3. "Popular applications like Slack and Discord, as well as our own application (BitMEX, a Bitcoin trading site) will be hugely and adversely affected by this."

      Slack bootstrap-client.js 7 setTimeout
      Slack rollup-client.js 8 setInterval , 121 setTimeout
      Slack rollup-core_required_lib.js 3 setInterval , 46 setTimeout

      Delete
    4. Callbacks from websocket data are also throttled by this intervention.

      Delete
  21. I agree with the idea of allowing a user to opt-in per tab. After all, it is their battery life to consume as they see fit. Obviously, the UX for this would have to be thought through.

    ReplyDelete
  22. I'm guessing you mean Web Workers and not Service Workers.

    ReplyDelete
  23. I already use The Great Suspender desktop Chrome extension to achieve much of this and it is really nice. https://github.com/deanoemcke/thegreatsuspender

    ReplyDelete
  24. All due respect, Chrome project has been on a *very* strange path for the past couple of years. I don't follow their team but my guess is they've switched leads. Their market share going into decline is a direct consequence.

    ReplyDelete
  25. Well, there are always other browsers. Chrome is becoming a new IE6. We are close to launch an open source XMPP web client, and if it won't work in background in chrome, well, we'd openly point users to Firefox.

    ReplyDelete
  26. Looks like Google is not shipping M56.
    http://www.itpro.co.uk/web-browsers/28004/google-almost-broke-the-web-with-its-latest-chrome-update

    ReplyDelete