New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 699559 link

Starred by 2 users

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 3
Type: Bug

Blocked on:
issue 668690



Sign in to add a comment

Play Music (web) has high cpu load due to compositor even when the window is bg

Project Member Reported by primiano@chromium.org, Mar 8 2017

Issue description

OS: OSX
Chrome: 59.0.3035.0 (Official Build) canary (64-bit)

Play music causes a constant ~20-30% cpu usage (my laptop gets mildly warm) when play music is the active tab, regardless of the fact that the chrome window itself is foreground or not. 

In other words:
- If I open play music and then open another tab (so play music is NOT the active tab), the cpu usage is reasonably low (1% or so)
- If I open play music and it is the active tab, cpu usage is high (20%-30%), even if the entire chrome window is not visible.

I attached a trace (look at pid 77848).
In the first 6 seconds play music is the active tab but not the FG window (I opened chrome://tracing in another fullscreen window). around T=6 s I went back to the play music window and opened about:blank.
If you look at PID 77848 there is a visible difference in the messageloop activity. It seems mostly compositor activity (BeginMainFrame and all related raster & uploads).

My major concern here is: why something happens where chrome is not fg (not even partially)? We seem to be doing the right thing when the tab itself is not active, but somehow we seem to lose consciousness when the window itself is not fg.

Adding some random cc folks on top of my head to help triaging this.

(Somehow I suspect that the fact that play music is playing audio might screw up our heuristics for the notion of "foreground")

Completely unrelated there is another issue: why we take 20%-30% CPU for play music when it's active AND foreground? It looks almost idle to me? The only things that are moving are the track progress bar and the tiny music GIF overlaid on top of the current album. But that's something like 200 pixels in total.
Anyway, this is a different problem, honestly the former (cpu usage non-FG case) worries me the most. I expect chrome to not eat my battery if I am not actively using it.

 
trace_playmusic.json.gz
4.3 MB Download
I don't know any any signal in the renderer process about visiblity other than being a background tab within a window. I don't know that even minimizing the chrome window tells the renderer anything. It would seem to be a pretty big UX change to do so, but would potentially be valuable.
Cc: haraken@chromium.org ericrk@chromium.org
+haraken FYI for memory-related considerations.
So, If I read #1 correctly, it seems that the renderer doesn't have any way to tell when it's backgrounded (I wonder, is this even the case on Android or things are different there because there is effectively no window?).
Which makes me suspect that at this point we don't even drop below the fold tiles to save memory when the window goes to bg, as opposite to the tab.
I believe we treat background app like background tab on Android, I meant to speak to desktop only.
Cc: tjsavage@chromium.org

Comment 5 by shrike@chromium.org, Mar 13 2017

primiano@ - can you provide mode info about where in Google Play music you are? E.g. a URL, or confirm that you're playing music (or not), etc.?

Re: foreground/background, I believe that status is influenced by whether or not the tab is playing music, but in general it's tied to whether or not the tab is the foreground tab in its window, not it's window's foreground status.

When a tab is in the background state it's timers are throttled to 1Hz. If the tab is the foreground tab in its window but its window is not the foreground window, that means the user can still see its content (if it's uncovered). It has to run in foreground mode because otherwise the user can potentially see it running in a throttled state.

You mention 20%-30% CPU when the window is not visible. There are hooks for occlusion state changes, so there should be a difference in this case - what are your exact steps for making the window not visible?

> primiano@ - can you provide mode info about where in Google Play music you are? E.g. a URL, or confirm that you're playing music (or not), etc.?

oops, sorry, right: https://play.google.com/music/listen
Essentially the frontend you would use to listen music from desktop.

> but in general it's tied to whether or not the tab is the foreground tab in its window, not it's window's foreground status.
I understand this. I guess my question is: is that an actual design decision (if so, why?) or it just happens to be the current implementation?

>what are your exact steps for making the window not visible?
Alt tab and switch to another window (in my case, my editor or the terminal)
> If the tab is the foreground tab in its window but its window is not the foreground window, that means the user can still see its content (if it's uncovered).

I guess this is my major question/objection here. In my case the chrome window was fully occluded. I think that in these cases we should treat all tabs of the window as background, because they are. Having said this, not sure if we have any OS primitive to know whether we are not foreground but still partially visible, or fully occluded.
by quickly digging in the code, it seems that we have an occlusion signal today, which goes from
web_contents_view_mac.mm windowChangedOcclusionState:(NSNotification*)notification 
all the way down to
web_contents_impl.cc WebContentsImpl::WasOccluded()

which should tell whether the window is fully occluded or not (from [1]: "When the value of this property is NSWindowOcclusionStateVisible, at least part of the window is visible; otherwise, the window is fully occluded.")

However, that seems to not do anything in non-testing code. So, unless I am missing something, that feature exists only for the sake of getting test coverage :/

The comment in public/browser/render_widget_host_view.h even says

 // Indicates if the view is currently occluded (e.g, not visible because it's
 // covered up by other windows), and as a result the view's renderer may be
 // suspended.

However that doesn't see to match what really happens (or am I just misreading the code)

[1] https://developer.apple.com/reference/appkit/nswindow/1419321-occlusionstate?language=objc
Cc: piman@chromium.org vmi...@chromium.org
+piman@ vmiura@

There have been reports of Chrome performing poorly when multiple Chrome windows are open. I wonder if those cases suffer from similar problems as described here. I think this is easy to run into on mac where users open a lot of windows, most of which are occluded, but don't really minimize/hide them and instead switch between windows using gestures. Should we Hide the renderer in such cases?
Like everything else, there is a UX trade-off. If we consider the tab "hidden" when occluded, we'll drop resources and it may flash when it becomes visible again.
Cc: nduca@chromium.org
Could we throttle graphics updates for occluded frames?

nduca@ proposed looking into ways to throttle foreground tabs that burn power.  Foreground+hidden may fall into that.
Cc: enne@chromium.org
We could lower the frame-rate by having the top level BeginFrameSource know this state and not send every beginframe (maybe SetNeedsBeginFrames(true/false/lowres)? We could also lower the js timer resolution like we do for background tabs.
Owner: enne@chromium.org
Status: Assigned (was: Untriaged)
Would the suggestion in comment #12 make sense?

Comment 14 by enne@chromium.org, May 1 2017

Cc: sunn...@chromium.org
Owner: ----
Status: Available (was: Assigned)
It seems reasonable to me to treat fully occluded windows like backgrounded windows if that primitive of detecting occlusion is available.

I'm not sure if we're throttling begin frames for background tabs at the moment, but that seems like something we should do as well.

Comment 15 by ojan@chromium.org, May 1 2017

Cc: altimin@chromium.org skyos...@chromium.org
AFAIK, we treat fully occluded windows the same background ones on the Mac (and maybe ChromeOS), but not other platforms, i.e. we don't run rAF and throttle timers. It's not clear to me from this thread. Did anyone compare fully occluded to background tab CPU performance here? If they are different, then that's just a bug and not intended behavior.

@enne: Agree that we should throttle begin frames for background tabs if we're not already. We throttle rAF, but I don't know how high in the pipeline that goes. The higher the better obvs. :)

altimin/skyostil: At some point we should think about what our options are for throttling background tabs that use audio. We have bigger fish to fry at the moment, but at some point we'll need to make this case less power hungry.

Comment 16 by ojan@chromium.org, May 1 2017

Cc: ojan@chromium.org

Comment 17 by ojan@chromium.org, May 1 2017

Components: Programs>Alignment
Re #15: I have an idea which might be able help in this situation: per-origin scheduling. Currently if we have an audio (or websocket or webrtc) we will grant exception to the whole page. We should restrict this exception to the frames with the same origin (e.g. main page audio does not prevent third-party iframes from being throttled).

Comment 19 by ojan@chromium.org, May 1 2017

I think that idea makes sense, but won't address this specific case since the Play Music case is probably all first party code.

Comment 20 by ojan@chromium.org, May 1 2017

Maybe what we do for first party code is shame them into fixing via things like a public power report and/or something like issue 37761.
Re #15-#20, note that everything seems fine when the PlayMusic *tab* is background, so not sure if this is something that PlayMusic should fix or this is just us (unless we are now discussing the case of it being in foreground, which is a different story).

I am not sure whether this issue will be solved by just throttling graphics. A part of me is still wondering: can we just treat fully occluded tabs in the same way we treat background tabs and reuse those code paths?
#21: Yes, we should treat fully occluded windows the same as background tabs. That should solve this particular problem as far as I can tell, or am I missing something?

Comment 23 by ojan@chromium.org, May 4 2017

It solves half of the problem. The other half is why it uses so much CPU in the foreground.

In either case, we should make sure fully occluded windows do actually behave the same as background tabs. When I had tested this in the past on Mac, they did get throttled when occluded, but maybe we don't hook at up properly to the new time-based system?

Comment 24 by ojan@chromium.org, May 5 2017

Yeah, RenderWidget::OnWasHidden doesn't seem to be doing the right thing. It goes to RendererSchedulerImpl::SetAllRenderWidgetsHidden, which doesn't set pagevisibility state or throttle.

I'm confused because I had a test case for this that did throttle when occluded. I don't have a mac accessible at the moment to double check though.

See related  issue 641045  which also has a test case.


Comment 25 by ojan@chromium.org, May 5 2017

Components: Blink>Scheduling
Project Member

Comment 26 by sheriffbot@chromium.org, May 7 2018

Labels: Hotlist-Recharge-Cold
Status: Untriaged (was: Available)
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue.

Sorry for the inconvenience if the bug really should have been left as Available.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Blockedon: 668690
Status: Available (was: Untriaged)
Owner: fdoray@chromium.org
Status: Assigned (was: Available)
Assigning this to François who is driving occlusion detection effort.

Sign in to add a comment