Closed
Bug 930587
Opened 11 years ago
Closed 11 years ago
[Homescreen] Style manipulation is expensive
Categories
(Firefox OS Graveyard :: Gaia::Homescreen, defect)
Tracking
(blocking-b2g:koi+, b2g-v1.2 fixed)
Tracking | Status | |
---|---|---|
b2g-v1.2 | --- | fixed |
People
(Reporter: BenWa, Assigned: eeejay)
References
Details
(Keywords: perf, Whiteboard: [c= p= s= u=1.2])
Attachments
(3 files)
734 bytes,
patch
|
Details | Diff | Splinter Review | |
1.34 KB,
patch
|
dholbert
:
feedback+
BenWa
:
feedback-
|
Details | Diff | Splinter Review |
358 bytes,
text/html
|
crdlc
:
review+
|
Details |
The homescreen uses a data-transitioning CSS selector. Toggling this needs to update the style of the children of that which currently is applied on the body element:
body[data-transitioning] .apps > div
This causes a full style flush for the document which takes over 16ms. We can't afford to this at all during the start touch event.
I also noticed that the Homescreen changes the visibility attribute. It appears to be done for performance however this prevent optimizations like pre-rendering from working properly. We need to tweak the app to force active layers and pre-render the other page. This way when a pan start we can start the animation immediatly and not have to perform any expensive style flush and paints.
The delay for the first frame is 100ms: 30ms for layout and 70ms for painting.
Reporter | ||
Comment 1•11 years ago
|
||
Here's a profile:
http://people.mozilla.org/~bgirard/cleopatra/#report=1a16c320066e2be47f40d07f2c6eb96f3f30a2de
Sorry there's a lot of advanced features turned on so it's difficult to read.
Comment 2•11 years ago
|
||
this issue blocks 920921, according to triage result, mark it koi+
blocking-b2g: --- → koi+
Comment 3•11 years ago
|
||
(In reply to Benoit Girard (:BenWa) from comment #0)
> Created attachment 821753 [details] [diff] [review]
> test to stop the restyle
>
> The homescreen uses a data-transitioning CSS selector. Toggling this needs
> to update the style of the children of that which currently is applied on
> the body element:
> body[data-transitioning] .apps > div
>
> This causes a full style flush for the document which takes over 16ms. We
> can't afford to this at all during the start touch event.
>
> I also noticed that the Homescreen changes the visibility attribute. It
> appears to be done for performance however this prevent optimizations like
> pre-rendering from working properly. We need to tweak the app to force
> active layers and pre-render the other page. This way when a pan start we
I tried to set layer.force-active flag on b2g, but I still could see the layer recreation when scroll to new pages. Not sure it is the right behavior or not.
I got a question here. If homescreen didn't change the visibility attribute, the layer which contains one page and is out of screen will be kept or removed because out of screen.
Reporter | ||
Updated•11 years ago
|
Attachment #821753 -
Attachment is patch: true
Attachment #821753 -
Attachment mime type: text/x-patch → text/plain
Comment 4•11 years ago
|
||
Benwa, did you see buffer re-allocation when scroll homescreen to new page? I still saw it after applying your test patch.
Reporter | ||
Comment 5•11 years ago
|
||
(In reply to peter chang[:pchang] from comment #3)
> I tried to set layer.force-active flag on b2g, but I still could see the
> layer recreation when scroll to new pages. Not sure it is the right behavior
> or not.
>
I would expect it to work but I don't know for sure.
> I got a question here. If homescreen didn't change the visibility attribute,
> the layer which contains one page and is out of screen will be kept or
> removed because out of screen.
I asked roc and he said if the layer is active and within 32 pixels of the screen it should be pre-rendered. We need to figure out why it doesn't happen like according to plan.
The pre-rendering isn't working properly but I don't know why. We will need a debugging session to see what decides to recreate or invalidate the buffer.
Peter,
nsDisplayTransform::ShouldPrerenderTransformedContent is the function to determine whether prerender a layer. FYI
http://dxr.mozilla.org/mozilla-central/source/layout/base/nsDisplayList.cpp#l4197
Comment 7•11 years ago
|
||
(In reply to Benoit Girard (:BenWa) from comment #5)
> (In reply to peter chang[:pchang] from comment #3)
> > I tried to set layer.force-active flag on b2g, but I still could see the
> I asked roc and he said if the layer is active and within 32 pixels of the
> screen it should be pre-rendered. We need to figure out why it doesn't
> happen like according to plan.
>
> The pre-rendering isn't working properly but I don't know why. We will need
> a debugging session to see what decides to recreate or invalidate the buffer.
To make pre-rendering work and no gralloc re-allocation, we need two things.
a. Align current page coordination with previous and next pages, like page1(-320, 0) page2(0,0) page3 (320, 0) if screen width is 320.
b. Set transfrom-style:preserve-3d and call transform: rotateY(1deg)
If we modified homescreen with above item b, the ShouldBuildLayerEvenIfInvisible(pre-render) will become true. And then it will construct a layer for current frame.
http://mxr.mozilla.org/mozilla-central/source/layout/base/FrameLayerBuilder.cpp#2123
[Pre-render]
The following lines are related code for pre-render condition check.
ShouldBuildLayerEvenIfInvisible(FrameLayerBuild.cpp)
-> nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayList.cpp)
-> nsIFrame::AreLayersMarkedActive(nsFrame.cpp)
-> Check Preserve3D property
http://mxr.mozilla.org/mozilla-central/source/layout/base/FrameLayerBuilder.cpp#2109
http://mxr.mozilla.org/mozilla-central/source/layout/base/nsDisplayList.cpp#4209
http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsFrame.cpp#4675
Comment 8•11 years ago
|
||
https://github.com/cctuan/gaia/commits/test222
we had co-worked with TPE gaia George and use above github for testing.
Updated•11 years ago
|
Whiteboard: [c= p= s= u=1.2]
Comment 9•11 years ago
|
||
Updating Target Milestone for FxOS Perf koi+'s.
Target Milestone: --- → 1.2 C4(Nov8)
Comment 10•11 years ago
|
||
(In reply to peter chang[:pchang] from comment #7)
> (In reply to Benoit Girard (:BenWa) from comment #5)
> > (In reply to peter chang[:pchang] from comment #3)
> > > I tried to set layer.force-active flag on b2g, but I still could see the
> > I asked roc and he said if the layer is active and within 32 pixels of the
> > screen it should be pre-rendered. We need to figure out why it doesn't
> > happen like according to plan.
> >
> > The pre-rendering isn't working properly but I don't know why. We will need
> > a debugging session to see what decides to recreate or invalidate the buffer.
>
> To make pre-rendering work and no gralloc re-allocation, we need two things.
> a. Align current page coordination with previous and next pages, like
> page1(-320, 0) page2(0,0) page3 (320, 0) if screen width is 320.
> b. Set transfrom-style:preserve-3d and call transform: rotateY(1deg)
>
> If we modified homescreen with above item b, the
> ShouldBuildLayerEvenIfInvisible(pre-render) will become true. And then it
> will construct a layer for current frame.
>
> http://mxr.mozilla.org/mozilla-central/source/layout/base/FrameLayerBuilder.
> cpp#2123
>
> [Pre-render]
> The following lines are related code for pre-render condition check.
> ShouldBuildLayerEvenIfInvisible(FrameLayerBuild.cpp)
> -> nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayList.cpp)
> -> nsIFrame::AreLayersMarkedActive(nsFrame.cpp)
> -> Check Preserve3D property
>
> http://mxr.mozilla.org/mozilla-central/source/layout/base/FrameLayerBuilder.
> cpp#2109
> http://mxr.mozilla.org/mozilla-central/source/layout/base/nsDisplayList.
> cpp#4209
> http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsFrame.cpp#4675
In, ContainerState::ProcessDisplayItems
http://mxr.mozilla.org/mozilla-central/source/layout/base/FrameLayerBuilder.cpp#2109
if (itemVisibleRect.IsEmpty() &&
!item->ShouldBuildLayerEvenIfInvisible(mBuilder)) {
continue;
}
Which means if you want a layer be pre-rendering and reserve only if
1. That item intersect wit view port
2. A item which is outside of viewport, it need to pass test in ShouldBuildLayerEvenIfInvisible.
I think we can use condition of #1, make left and right page be intersect with viewport by 1 pixel.
Comment 11•11 years ago
|
||
BenWa, I'm setting you as the assignee for this bugs since you've submitted a path. If you're not the right person for this please reply saying so.
Assignee: nobody → bgirard
Status: NEW → ASSIGNED
Flags: needinfo?(bgirard)
Reporter | ||
Comment 12•11 years ago
|
||
I'd rather pass this on to the app developers since they know this code better. There's other platforms issues that need to be fixed for the homescreen and this is purely a problem on the app side.
Looks like Eitan wrote the initial code. Can you look into reworking the style change? I'd imagine setting the style directly on what needs it would solve the problem. Or avoiding this entirely would help the time to the first frame on touch down. For more complex cost questions of manipulating styles needinfo dholbert.
Assignee: bgirard → nobody
Flags: needinfo?(bgirard) → needinfo?(eitan)
Reporter | ||
Comment 13•11 years ago
|
||
This is great info CJKu and pchang. Let's move that discussion to bug 931262 and leave this bug strictly as an app issue to rewrote how it manipulate styles to avoid an expensive flush.
Comment 14•11 years ago
|
||
inline
(In reply to Benoit Girard (:BenWa) from comment #0)
> Created attachment 821753 [details] [diff] [review]
> test to stop the restyle
>
> The homescreen uses a data-transitioning CSS selector. Toggling this needs
> to update the style of the children of that which currently is applied on
> the body element:
> body[data-transitioning] .apps > div
>
> This causes a full style flush for the document which takes over 16ms. We
> can't afford to this at all during the start touch event.
1. This rule could be avoided by means of body[data-mode='edit'] (it is used to stop the bouncing effect of icons while panning)
body[data-mode='edit'][data-transitioning] ol > li > div > img
https://github.com/mozilla-b2g/gaia/blob/master/apps/homescreen/style/dragdrop.css#L55
2. Read about accessibility, see below
https://github.com/mozilla-b2g/gaia/blob/master/apps/homescreen/style/grid.css#L29
3. This rule could be removed because this stops the installing animation around an icon while panning (edge case)
https://github.com/mozilla-b2g/gaia/blob/master/apps/homescreen/style/grid.css#L155
>
> I also noticed that the Homescreen changes the visibility attribute. It
> appears to be done for performance however this prevent optimizations like
> pre-rendering from working properly. We need to tweak the app to force
> active layers and pre-render the other page. This way when a pan start we
> can start the animation immediatly and not have to perform any expensive
> style flush and paints.
The visibility changes were introduced for accessibility https://github.com/mozilla-b2g/gaia/commit/08ba523403475799861b06166391811226c8a0c8. From my point of view, all stuffs about visibility could be removed thought :)
>
> The delay for the first frame is 100ms: 30ms for layout and 70ms for
> painting.
Assignee | ||
Comment 15•11 years ago
|
||
(In reply to Benoit Girard (:BenWa) from comment #12)
> Looks like Eitan wrote the initial code. Can you look into reworking the
> style change? I'd imagine setting the style directly on what needs it would
> solve the problem. Or avoiding this entirely would help the time to the
> first frame on touch down. For more complex cost questions of manipulating
> styles
The two alternatives would be (a) style the actual list items as invisible, would that help? or (b) use aria-hidden, which requires some js hoopla and has the danger of decoupling from the actual visual state.
Flags: needinfo?(eitan)
Assignee | ||
Comment 16•11 years ago
|
||
Attachment #826828 -
Flags: feedback?(bgirard)
Reporter | ||
Comment 17•11 years ago
|
||
Comment on attachment 826828 [details] [diff] [review]
Style individual app icons instead of full pages.
Bouncing this to dholbert from lack of CSS knowledge.
Attachment #826828 -
Flags: feedback?(bgirard) → feedback?(dholbert)
Comment 18•11 years ago
|
||
Comment on attachment 826828 [details] [diff] [review]
Style individual app icons instead of full pages.
At a purely "is this valid CSS" level, this looks fine.
(IIUC, this is styling the app icons to be invisible, except for those on the current page, and also except for when the user is swiping the homescreen side to side.)
This should be an improvement, from the perspective of making style changes more granular. I'm not sure it addresses the issue that BenWa brought up at the end of comment 0, though. (BenWa said there that visibility:hidden prevents "optimizations like pre-rendering from working properly") BenWa, do you know (or, can you test) to see if this helps at all?
From that standpoint, it may end up being better to drop these "visibility" declarations altogether and using aria-hidden -- Eitan's option (b).
Attachment #826828 -
Flags: feedback?(dholbert)
Attachment #826828 -
Flags: feedback?(bgirard)
Attachment #826828 -
Flags: feedback+
Reporter | ||
Comment 19•11 years ago
|
||
I don't know much about accessibility . I'm guessing aria-hidden is something to tell the screen reader to ignore it. For non accessibility performance making something that's near offscreen hidden will make performance worse because we will make the wrong decisions and incur more work and/or miss optimization.
I guess the question then is how to best have accessibility deal with things that are offscreen? Then I don't know. Ideally it can perform visibility testing properly but in the worse case if aria-hidden has no side effect for non accessibility it should fix this performance problem.
Reporter | ||
Updated•11 years ago
|
Attachment #826828 -
Flags: feedback?(bgirard) → feedback-
Comment 20•11 years ago
|
||
It looks like Eitan took this. We just want to make sure the assignee is set so we can see if any koi+ bugs aren't covered. Eitan please fix if you're not actively working this.
Assignee: nobody → eitan
Assignee | ||
Comment 21•11 years ago
|
||
Pointer to Github pull-request
Assignee | ||
Updated•11 years ago
|
Attachment #828187 -
Flags: review?(crdlc)
Comment 22•11 years ago
|
||
Comment on attachment 828187 [details]
Pointer to Github pull request: https://github.com/mozilla-b2g/gaia/pull/13439
Great work! Thanks a lot my friend!
Attachment #828187 -
Flags: review?(crdlc) → review+
Comment 23•11 years ago
|
||
Status: ASSIGNED → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Reporter | ||
Comment 24•11 years ago
|
||
Thanks Eitan.
I think this will have some improvements but I still expect to see some big Style blocks showing up in profiles but this means we can move into the next issue!
Comment 25•11 years ago
|
||
Uplifted e8fbba0c9716d3a4454ed171ca7b4410b9c4bd9d to:
v1.2: 244ec6e3afa470667c8dfd63dc8cf7a0c1fd6590
status-b2g-v1.2:
--- → fixed
You need to log in
before you can comment on or make changes to this bug.
Description
•