[css-contain] Very poor layout performance in Construct 3 PWA
Reported by
a...@scirra.com,
Jun 7 2017
|
||||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3122.0 Safari/537.36 Steps to reproduce the problem: 1. Download this file: https://cdn.discordapp.com/attachments/225550155531812865/321301531569684480/Event_Delay.c3p 2. Visit https://editor.construct.net 3. Drag-and-drop the file in to the browser window. It should open the project. 4. While recording performance, click the "expand" icon on the first row a few times. The exact place to click is circled in red in this picture: https://dl.dropboxusercontent.com/u/15217362/expand-event-arrow.png In dev tools, this simple act of hiding/showing some DOM elements causes 830ms of "Recalculate Style" followed by 733ms of "Layout", on a high-end dev machine. Other users are complaining it takes several seconds. What is the expected behavior? Layout performance should be faster, ideally <50ms to be within the threshold of perceiving as instant. What went wrong? Simple expand/collapse operation can take several seconds to layout. Did this work before? N/A Does this work in other browsers? N/A Chrome version: 61.0.3122.0 Channel: canary OS Version: 10.0 Flash Version: The layout being expanded/collapsed is largely based on CSS Grid, so this may be specific to CSS grid layout performance.
,
Jun 12 2017
Tested the issue on chrome Stable #59.0.3071.86, #61.0.3122.0 and Canary #61.0.3128.0 in Windows 10.0 and was able to reproduce the issue. Observations: ------------- Provided URL supported from version M57 #57.0.2940.0 (Layout > 5900ms ,Recalculate Style > 4100ms) Win - Latest Canary #61.0.3128.0 (Layout > 17,000ms ,Recalculate Style > 4300ms) Mac - Latest Canary #61.0.3128.0 (Layout > 900ms , Recalculate Style > 1500ms) Linux - Latest Canary #61.0.3128.0 (Layout > 2300ms , Recalculate Style > 1900ms) This is a Non-Regression issue since seeing this from M57 #57.0.2940.0, Making the status to Untriaged so that the issue would get addressed. Note : Able to reproduce the issue in MAC 10.12 and Linux Ubuntu 14.04. Thank you.
,
Jun 12 2017
What makes you think this is a Chrome bug? Could you please provide a reduction demonstrating the problem?
,
Jun 12 2017
It's not that complicated a layout, why should it take so long to calculate? Is there anything I can do to better investigate the problem? AFAIK there are no tools to help here. If you see 1s of layout in dev tools, how do you go about figuring out why that is, or what's causing that? Is there any kind of layout profiler?
,
Jun 26 2017
The combination of very long recalc style times and very long layout times seems to indicate either a very deep DOM or very large document. The easiest way to determine where the problem lies would be to bisect it. Try isolate the part that is the slowest by selectively removing/disabling parts of it. The chrome profiler can be a good help but would require familiarity with the web app in question. If there is a specific type of layout that is much slower than you think it should be and that can be reproduces outside of a very large web app we can certainly look into it. It is not practical for us to investigate performance aspects of third party applications, especially not once as large as Construct which loads over 500 resources just to present the initial screen.
,
Jun 26 2017
Oddly enough loading 500 resources is done faster than expanding that DOM element. Would be great to know if this a current limitation of Google Chrome for future web app development. Thanks
,
Jun 26 2017
The Chrome profiler is no help here - as I said in the original report, all it tells us is that it spent a long time in "recalculate style" and "layout". With JavaScript code you can dig in to flame charts of where time is spent, but this part of Chrome is a black box. I'll try to make a standalone repro, but I was at least hoping someone from Google would be able to identify why this layout takes so long or what could possibly be changed about it. It's a surprising result to me since it's not a deep or even particularly large amount of DOM content, just a lot of consecutive CSS grid rows, which takes extraordinarily long to do layout for.
,
Jun 27 2017
I think it is also revealing to contrast this with the V8 team's approach to performance: ditching benchmarks in favour of profiling and optimising real-world apps and pages. If we take our real-world DOM content out of our app, we are starting down the path of synthetic benchmarks, which the V8 team have recently done a good job of covering the shortcomings.
,
Oct 10 2017
For reference (in helping to decide how to prioritize problems like this) here's some data from the Blink.StyleAndLayout.UpdateTime UMA histogram about how long style update and layout take in practice in the wild on Android: 50th: 0.05ms, 95th: 2ms, 99th: 6ms, 99.9th: 73ms (and the general trend over the past year has been slightly down).
,
Oct 10 2017
And on Windows: 50th: 0.008ms, 95th: 0.9ms, 99th: 3ms, 99.9th: 20ms, 99.99th: 73ms Of course the denominator for this measurement (count of layouts) isn't ideal (since adding more fast layouts would improve the metrics). Perhaps it would be more useful to know total layout time per frame or something?
,
Dec 8 2017
,
Dec 8 2017
Re-opening this bug to investigate further. Findings: 1. The style updates happen because opening and closing the "expand" icon use display:none and display:block to change modes. display:none destroys all style, layout and paint information about the subtree. Therefore re-creating that subtree causes all of this information to be re-created from scratch for the entire subtree. In this case the subtree is very large. Style is re-calculated for 27608 elements. Then layout occurs. There is grid layout specified, so grid layout on this many elements occurs, which has a lot of expense. 2. #1 is an "expected" behavior. display:none killing off of of that information is actually a nice feature and has good performance in many cases, because it saves memory and time for any updates that happen while the subtree is not displayed. For example, layout of the rest of the page is made much faster in this case due to not having to worry about that subtree. 3. If opening and closing the "expand" icon is a desired behavior to make fast (which it is in this UI), then display:none is not a good choice, for the reasons outlined above. Setting height:0px and overflow:hidden on the containing element is better. 4. #3 being said, the presence of the subtree leads to the optimizations we might get from #2 being lost. contain: contents is actually present already on the root element below the "expand" icon, so we should be able to still get good performance performing layout outside of the contain: contents element because we know that the layout doesn't need to flow inside of it, especially if the contain:contents element might have an explicit width and height. The person who reported this bug also confirmed offline to me that applying the suggestion in #3 works for making expand/collapse fast, but indeed has a very bad negative side-effect in #4. #4 is the part that I think is an actionable next step to fix.
,
Dec 8 2017
,
Oct 1
,
Oct 19
,
Dec 13
|
||||||||||
►
Sign in to add a comment |
||||||||||
Comment 1 by nyerramilli@chromium.org
, Jun 8 2017