News for hackers. Stuff that matters.
Re:Chrome will aggressively throttle background tabs by artursapek on Tuesday January 24, 2017 @01:09PM (#13473859)
I run a real time charting platform for Bitcoin traders (like those using BitMEX) and the app does a lot of updating/refreshing. I recently learned of the visibilitychange API and managed to make huge improvements in the app's performance when running in the background - on the order of ~75% reduction in CPU usage when running in the background. [1]

    var doVisualUpdates = true;

    document.addEventListener('visibilitychange', function(){
      doVisualUpdates = !document.hidden;
    });
Basically, you can use this to determine if your tab is running "in the background" and avoid redrawing/refreshing components to show updates that won't ever be seen.

[1] https://twitter.com/cryptowat_ch/status/817502626896089090

Re:Chrome will aggressively throttle background tabs by STRML on Tuesday January 24, 2017 @01:35PM (#13474118)
Yeah - that's a really great trick! You can also get this somewhat "for free" by batching updates on `requestAnimationFrame`, which never fires when unfocused.

https://www.npmjs.com/package/visibility is a nice little package that encapsulates some of the browser compat issues, if you have out-of-date clients.

Re:Chrome will aggressively throttle background tabs by artursapek on Tuesday January 24, 2017 @02:09PM (#13474459)
But if you do this, isn't it possible that you'll queue up tons of re-renders that all go off when the tab comes back in focus? I'm thinking of React for example, where you might re-render a component with updated props several times per second. In my case, I've settled on just not re-rendering at all, and then doing so once with the latest props when "visibility" fires again with document.hidden === true.
Re:Chrome will aggressively throttle background tabs by STRML on Tuesday January 24, 2017 @02:47PM (#13474803)
This is where batched rendering really comes in handy. For example:

https://gist.github.com/STRML/cc368c46c2d7de8679196e69ddbcae...

The key is, even in your case (with price alerts), you'll still want to tick occasionally, thus the `FORCE_TICK_INTERVAL`.

React's own batching is smart enough to merge the work. For example, before the next tick, one component calls setState() 20 times, another calls it once. Only one rerender will actually be done.

Some more discussion on rAF batching here: https://github.com/petehunt/react-raf-batching/issues/8

Re:Chrome will aggressively throttle background tabs by SapphireSun on Tuesday January 24, 2017 @03:08PM (#13474986)
I'm not a graphics expert, but one really easy change to make is a pattern like this:

    _needsrender = false;
    
    function render () {
        _needsrender = true;
    }

    requestAnimationFrame(function hardrender () {
         if (_needsrender) { 
          .... do stuff ....
          _needsrender = false;
         }
         requestAnimationFrame(hardrender);
    });
Re:Chrome will aggressively throttle background tabs by just2n on Tuesday January 24, 2017 @02:49PM (#13474819)
Why not limit it to a single render queued with the latest information?

I see this done via debouncing for render operations that happen on repeated events, for instance typing (send query to server, then show matching results in a render of some list).

Re:Chrome will aggressively throttle background tabs by Kiro on Wednesday January 25, 2017 @10:28AM (#13482130)
Yes, this happens in my browser games. When the user clicks back to the tab it fires off all the frames that have been queued up, moving everything in hyperspeed until it's up to date. I don't really mind though, since it's multiplayer it's supposed to catch up but doesn't need to render when unfocused.
Re:Chrome will aggressively throttle background tabs by daveheq on Tuesday January 24, 2017 @05:27PM (#13476341)
Why should the browser rely on the webpage developer to tell it to not redraw things in a tab that isn't the visible one? The browser by default shouldn't redraw content in a tab that isn't visible. This seems like the most obvious thing in the world.
Re:Chrome will aggressively throttle background tabs by Filligree on Tuesday January 24, 2017 @05:33PM (#13476387)
It depends on how you define "Visibility changes".

What might he be talking about? Well, it works something like this...

- The app fetches data from a server.

- The data is processed. This may be cheap, or expensive.

- The DOM is updated.

- The page layout is recomputed.

- The browser window is redrawn.

Certainly, the browser could skip the last step for invisible tabs. It can't skip redoing the layout, as the JS can read the computed layout back out; at most it could do the computation lazily, but that would be extra code and complexity. Everything prior to that step isn't under the browser's control.

The web-app coder could act on every single step in the chain, starting by throttling data fetches.

Re:Chrome will aggressively throttle background tabs by odbol_ on Tuesday January 24, 2017 @09:17PM (#13477854)
Because some websites might still need to work when not in focus. E.g. If you are showing animations or videos in a window, but the user wants to answer an IM in another window without interrupting the animations.
Re:Chrome will aggressively throttle background tabs by 72deluxe on Wednesday January 25, 2017 @07:45AM (#13480924)
But then if you switch windows or tabs, the timer for the animations in the tab that is now invisible can be stopped, surely??

Why redraw an invisible window? In any ordinary paint routine, you query for the invalidated rectangle and only redraw what you must. In the case of pages that are out of view, then nothing needs redrawing.

Processes that are busy doing things they need not (like redrawing on a timer, polling a mouse) is why Apple starting highlighting offenders in macOS (what is hogging the battery??) and why I don't use Chrome on it - it just gobbles power keeping all of those tabs alive.

Hopefully these new changes will help.

Re:Chrome will aggressively throttle background tabs by artursapek on Wednesday January 25, 2017 @09:19AM (#13481497)
OP here. In my case, the CPU saved was mostly React updating its virtual DOM. Yes, the browser doesn't do repaints when the tab is in the background. But there's plenty of other work that is done before repaints when using a library like React.
Re:Chrome will aggressively throttle background tabs by vertex-four on Tuesday January 24, 2017 @05:31PM (#13476371)
It doesn't need to do the final step of rendering - but it still needs to reflow the page whenever you change the DOM, because information from that reflow is accessible to javascript.
Re:Chrome will aggressively throttle background tabs by glenscott1 on Wednesday January 25, 2017 @06:06AM (#13480418)
This is a great tip. To make it compatible with most modern browsers (Chrome, Firefox, Opera, Safari and MS), you'll need to use the following checks:

        if (typeof window.document.hidden !== 'undefined') {
            hidden = 'hidden';
        }
        else if (typeof window.document.msHidden !== 'undefined') {
            hidden = 'msHidden';
        }
        else if (typeof window.document.webkitHidden !== 'undefined') {
            hidden = 'webkitHidden';
        }

        doVisualUpdates = !window.document[hidden];

reference: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibi...
Re:Chrome will aggressively throttle background tabs by skilgarriff on Tuesday January 24, 2017 @02:11PM (#13474474)
If you happen to use React, I built a React component that helps you manage this! :) Hopefully it helps a bit! It also reports whether or not a user is idle, such that you can reduce cpu usage during that as well.

https://github.com/Skilgarriff/react-user-focus

Re:Chrome will aggressively throttle background tabs by LeanderK on Tuesday January 24, 2017 @03:11PM (#13475010)
i don't know anything about React, but why can't react itself try to manage this?
Re:Chrome will aggressively throttle background tabs by STRML on Tuesday January 24, 2017 @03:18PM (#13475061)
React is in the business of limiting its API surface, not increasing it. I think they have done a great job of it - libraries like this should exist in userland.
Re:Chrome will aggressively throttle background tabs by cpeterso on Tuesday January 24, 2017 @04:30PM (#13475703)
It seems like React could listen for visibilitychange itself to throttle its own events or virtual DOM processing. It wouldn't necessarily need to expose visibilitychange as a library API.
Re:Chrome will aggressively throttle background tabs by KirinDave on Tuesday January 24, 2017 @07:09PM (#13477110)
Because there is no sufficient magic for that. App developers have to think about when they do work, how much work they do, and if and when it should be rendered. For any rule you can give, I can give you an example of an app that would break.

In general, the mantra for people who find this tough to fix should be, "Why didn't I use MVC, what a cretin I was!"

Re:Chrome will aggressively throttle background tabs by trakout on Thursday January 26, 2017 @12:51PM (#13493486)
For animations/any sort of render loop, you can also make use of the requestAnimationFrame API, which auto-pauses when the tab is out of focus.

https://developer.mozilla.org/en-US/docs/Web/API/window/requ...

Re:Chrome will aggressively throttle background tabs by benjaminjackman on Tuesday January 24, 2017 @01:43PM (#13474207)
Wow that's a great tip, I did not know about that one, but it's going to be very useful for a UI I am about to start working on.

In addition to requestAnimationFrame this could be very handy!

Are there any gotchas you have experienced in using this API that I should look out for?

Re:Chrome will aggressively throttle background tabs by artursapek on Tuesday January 24, 2017 @02:11PM (#13474476)
Just look out for this not being supported and make sure your stuff still works. Eg, document.hidden might be undefined so don't initialize like this:

    doVisualUpdates = (document.hidden === true);
Re:Chrome will aggressively throttle background tabs by minitech on Tuesday January 24, 2017 @05:43PM (#13476476)
Well, you’d typically want to do visual updates when document.hidden wasn’t true, which would work fine.
Re:Chrome will aggressively throttle background tabs by ErikBjare on Wednesday January 25, 2017 @02:52AM (#13479572)
He probably meant `(browser.hidden === false)` which wouldn't work if browser.hidden is undefined. Use == instead of === and it will work fine.
Re:Chrome will aggressively throttle background tabs by artursapek on Wednesday January 25, 2017 @09:20AM (#13481505)
No, the opposite of that. If document.hidden === undefined, you don't want to use this optimization at all. What I was saying is, if you initialize doVisualUpdates as "document.hidden === true", in the case where it's undefined, you will never do visual updates.
Re:Chrome will aggressively throttle background tabs by minitech on Wednesday January 25, 2017 @05:02AM (#13480137)
`!document.hidden` would work, and it’s what most people would normally write already. `document.hidden == false` would not work; `false != undefined`.
Re:Chrome will aggressively throttle background tabs by conradfr on Wednesday January 25, 2017 @08:11AM (#13481101)
On the other hand, it gives us video ads that stop and resume when tabs are switched.
Re:Chrome will aggressively throttle background tabs by swah on Wednesday January 25, 2017 @06:35AM (#13480566)
You site is beautiful, very much like HN in the sense of showing lots of information vs following design trends: https://cryptowat.ch/
Re:Chrome will aggressively throttle background tabs by nkkollaw on Tuesday January 24, 2017 @05:28PM (#13476351)
Very nice.