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

Issue 752756 link

Starred by 3 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows , Mac
Pri: 2
Type: Bug



Sign in to add a comment

position: sticky/fixed; very degraded performance on page with large number of positioned elements

Reported by tom...@gmail.com, Aug 5 2017

Issue description

UserAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36

Steps to reproduce the problem:
Browse the ES6 spec page:

http://www.ecma-international.org/ecma-262/6.0/

section > h1 has "position: sticky;" at time of submission.

What is the expected behavior?

What went wrong?
My machine is not exactly new but the page scrolls at about 1 FPS and it's pure text, i'd imagine it's also bad on new machines.

In the profiler under interactions>input, "Mouse Wheel", "Scroll Begin", "Scroll Update" and "Scroll End" all take between 300ms and 600ms "waiting for main thread"

If you toggle the "position: sticky;" off in with the element inspector the page scrolls smoothly as expected.

Did this work before? N/A 

Does this work in other browsers? N/A

Chrome version: 60.0.3112.90  Channel: stable
OS Version: 4.6.7-040607
Flash Version:
 

Comment 1 by woxxom@gmail.com, Aug 5 2017

This is not a regression but the inherent deficiency of the implementation as observed on a fast Windows 7 desktop PC with i7 4GHz CPU.

Related CL:
  r386998 (52.0.2708.0) enables position:sticky when the following flag is enabled:
  chrome://flags/#enable-experimental-web-platform-features

  r429927 (56.0.2910.0) enables position:sticky by default even without the flag

Repro note: 
  1. load the URL in #0
  2. open Chrome Task Manager, make sure the tab has finished loading and CPU is 0
  3. switch to the page and press the Arrow Down key, don't release it
  4. observe the tab's CPU usage in Chrome Task Manager
EXPECTED:
  0 or 1%
  scrolling with mouse wheel is smooth
OBSERVED:
  max CPU core: 12% on 8-core, 25% on 4-core, etc.
  scrolling with mouse wheel is janky

Comment 2 by tom...@gmail.com, Aug 5 2017

If this is one of those tricky to optimise things, perhaps it should be disabled until something with reasonable performance is found.

It's really quite debilitating if someone pops it into a very long page, that ES6 spec was impossible for me to navigate until I figured out what was causing the lag.
Labels: Needs-Triage-M60
Components: Blink>CSS Blink>Layout
Labels: M-62 hasbisect-per-revision OS-Mac OS-Windows
Owner: flackr@chromium.org
Status: Assigned (was: Unconfirmed)
Able to reproduce the issue on Windows 10, mac 10.12.6 and Ubuntu 14.04 using chrome reported version #60.0.3112.90 and latest canary #62.0.3178.0 .

Bisect Information:
=====================
Good build: 52.0.2707.0    Revision(386876)
Bad Build : 52.0.2708.0    Revision(387197)

Change Log URL: 
https://chromium.googlesource.com/chromium/src/+log/db9bb0321229e099e96b9429d4c80565b79ec8c9..3b6513eaede077dc4171f5a05157a8658279a68a

From the above change log suspecting below change
Review url: https://codereview.chromium.org/1870663002

flackr@ - Could you please check whether this is caused with respect to your change, if not please help us in assigning it to the right owner.

Note: 
1. In M50, even after enabling the flag at chrome://flags/#enable-experimental-web-platform-features, the issue is not observed. Hence, it is a regression issue.
2. In OS-Mac, the CPU increases more than 100%, when scrolled using track pad.

Thanks...!!
Labels: Performance
Components: -Blink>CSS
Cc: smcgruer@chromium.org
A few notes:

1. There are 1699 h1 elements on that page, all of which will be sticky.

2. We generally have just straight lookups of sticky elements out of a HashTable, which should be reasonably fast.

3. I currently suspect LocalFrameView::UpdateLayersAndCompositingAfterScrollIfNeeded, since that does a straight walk over all viewport constrained objects (which sticky is). But that's just a gut feeling.
Attaching two traces taken on 60.0.3112.90 (Official Build) (64-bit) (cohort: Stable, Windows, with and without sticky.
trace_with_sticky.json.gz
392 KB Download
trace_without_sticky.json.gz
629 KB Download
Yep, that loop in LocalFrameView takes 100-200 milliseconds on my (rather powerful) Linux desktop.

[1:1:0808/144641.964276:5885881680281:INFO:LocalFrameView.cpp(2043)] smcgruer: loop of 1696 took 0.149737 s
[1:1:0808/144642.146172:5885881862183:INFO:LocalFrameView.cpp(2043)] loop of 1696 objects took 0.154006 s
[1:1:0808/144642.379009:5885882094994:INFO:LocalFrameView.cpp(2043)] loop of 1696 objects took 0.204888 s

Next step is to identify why we do it (I used to know this...) and if we can do it less often or determine which part of the loop is slow.
Cc: -smcgruer@chromium.org flackr@chromium.org
Owner: smcgruer@chromium.org
Ah, we are creating copies of the StickyConstraintsMap when we grab it. That will not be good for performance.

I believe I have a fix, so taking ownership of this bug.
Project Member

Comment 11 by bugdroid1@chromium.org, Aug 9 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/a58917c73b78cd83f34b99f2ced3ac33bb0f2648

commit a58917c73b78cd83f34b99f2ced3ac33bb0f2648
Author: Stephen McGruer <smcgruer@chromium.org>
Date: Wed Aug 09 15:19:23 2017

Access StickyConstraintsMap by reference in LocalFrameView

We were accidentally making copies of the StickyConstraintsMap inside
LocalFrameView::UpdateLayersAndCompositingAfterScrollIfNeeded, rather
than using the reference passed back by
PaintLayerScrollableArea::GetStickyConstraintsMap. On pages with large
number of sticky elements such copying had a large performance impact.
The fix is trivial - just use the reference.

Bug: 752756
Change-Id: I4be7c7c50a0ca001c3564bbc9f9ab7d9d418b6e9
Reviewed-on: https://chromium-review.googlesource.com/606949
Commit-Queue: Stephen McGruer <smcgruer@chromium.org>
Reviewed-by: David Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#492988}
[modify] https://crrev.com/a58917c73b78cd83f34b99f2ced3ac33bb0f2648/third_party/WebKit/Source/core/frame/LocalFrameView.cpp

Status: Fixed (was: Assigned)

Comment 13 by tom...@gmail.com, Aug 9 2017

Great, thanks!

Comment 14 Deleted

Status: Assigned (was: Fixed)
Tested the issue on Win-10, Mac 10.12.6 and Ubuntu 14.04 using latest chrome version #62.0.3181.0 as per comment #1. Observed that the issue is yet not fixed and CPU increases to 13% on OS-Win which is not as per expected. 
Note: On OS-Mac and OS-Linux, the CPU increases more than 100% upon scrolling with track pad and mouse wheel respectively.

Attached a screen cast for reference

Hence, reopening the issue by assigning to smcgruer@ for further action.

Thanks...!!


752756.mp4
11.1 MB View Download
Peeling the onion :). The performance has improved, scrolling is much less janky in 62.0.3181.0, but #15 is correct that there is still some jank and the CPU usage is too high when sticky is on.

Attaching a new set of traces, starting to dig into them.
Status: Started (was: Assigned)
(Turns out scrollwheel scrolls involve hit-testing and differ depending on where your mouse is. Changed the new traces to non-scrollwheel.)
trace_without_sticky.json.gz
7.6 MB Download
trace_with_sticky.json.gz
23.8 MB Download
flackr@ asked me to add a relative case for comparison, attaching.
trace_with_relative.json.gz
10.7 MB Download
Summary: position: sticky/fixed; very degraded performance on page with large number of positioned elements (was: position: sticky; extremely degraded performance)
The remaining performance problem is not isolated to sticky. Either sticky or fixed position will cause it (see attached position: fixed trace, of the same ecma page with the h1 position type changed).

The performance hit is also spread across the board: I tracked some of it to the call to 'layout_view_item.Layer()->SetNeedsCompositingInputsUpdate();' in LocalFrameView::UpdateLayersAndCompositingAfterScrollIfNeeded which means that we need to run compositing for every scroll event for fixed/sticky elements, but other parts of the pipeline are also 10x-100x slower with fixed/sticky: 	LocalFrameView::prePaint, LocalFrameView::paintTree, RecordingSource::FinishDisplayItemListUpdate being the main three culprits from the trace.

Given such a wide problem, I'm not really sure where to start. flackr, can you suggest some folks to cc?

I have attached two local repo copies of the ECMA page; one with sticky and one with fixed.

Note: All this work has been done on low-DPI where we don't promote anything on the ECMA page (either fixed or sticky version).
ecma-fixed-pos.tar.gz
4.6 MB Download
ecma-sticky-pos.tar.gz
4.6 MB Download
trace_with_fixed.json.gz
12.5 MB Download

Comment 22 by woxxom@gmail.com, Aug 10 2017

>Either sticky or fixed position will cause it

The issue 752818 might be related.
Cc: ericrk@chromium.org
Wondering if this is still happening on canary. This does look like issue 752818.
Labels: -Performance Performance-Loading
Strangely this already feels a lot better for me on 62.0.3202.75 (compared to 62.0.3181.0 mention in comment #16 above), and the CPU usage isn't going above a few percent on linux for http://www.ecma-international.org/ecma-262/6.0/, ecma-fixed-pos.tar.gz or ecma-sticky-pos.tar.gz.

I'm going to run a bisect between 62 and 61 and see if I can find any obvious point where things got better.
Cc: benhenry@chromium.org
Ok, so I was mistaken. The improvement in sticky in 62 was from merging crrev.com/a58917, but sticky and fixed are still both jankier than non-positioned.

I cannot reproduce the 100% CPU utilization I mentioned on Linux atm though.

benhenry@ - is there reason to believe this situation should have improved on canary?
I should note that fixed feels a lot jankier than sticky. Personally I would classify sticky on http://www.ecma-international.org/ecma-262/6.0/ as 'usable' now, but fixed as still too janky to be usable (though its unlikely any real website would make hundreds of headers fixed-pos!)
64.0.3258.0 (Developer Build) (64-bit) feels the same to me as stable for the fixed/sticky position test pages. I don't observe any change.
Thanks for the work, so this is still a problem. Is this something you can work on, or should we make this available?
Status: Available (was: Started)
Given that the sticky side seems 'ok' and the fixed much worse, this is not going to be high on my priority list. So let's mark it available.
Cc: smcgruer@chromium.org
Owner: ----
Components: -Blink>Scroll Internals>Compositing>Scroll

Sign in to add a comment