Bug 64851

Summary: Optimize AnimationController::updateAnimations
Product: WebKit Reporter: zeng huiqing <huiqing.zeng>
Component: Layout and RenderingAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: cmarrin, darin, dbates, dglazkov, dino, hyatt, morrita, simon.fraser, tonikitoo, webkit.review.bot
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: All   
Attachments:
Description Flags
Optimize AnimationController::updateAnimations
webkit.review.bot: commit-queue-
newPatch
simon.fraser: review-
newPatch
none
newPatch none

Description zeng huiqing 2011-07-20 01:04:47 PDT
For loading page w/ transition property(CSS3), FF4 ~5.5X faster than Chromium.

Through analysis, we find that the root cause is that w/ transition, when a dom element is attached, it will call RenderObject::setAnimatableStyle, then AnimationController::updateAnimations, and it will call AnimationController::updateAnimationTimer, which is the hotspot.
Comment 1 zeng huiqing 2011-07-20 01:33:30 PDT
Created attachment 101436 [details]
Optimize AnimationController::updateAnimations

In my opinion, in fact, we may do not need to call updateAnimationTimer in the process of "Attach" when loading page.

Has submit a patch, the patch is to add flag in function setAnimatableStyle() and updateAnimations() to avoid calling updateAnimationTimer when doing "Attachment". The patch will reduce page(with transition property) loading time by 70%, improve the performance by 3.3X.
Comment 2 WebKit Review Bot 2011-07-20 02:16:06 PDT
Comment on attachment 101436 [details]
Optimize AnimationController::updateAnimations

Attachment 101436 [details] did not pass chromium-ews (chromium-xvfb):
Output: http://queues.webkit.org/results/9192186

New failing tests:
animations/animation-end-event-short-iterations.html
Comment 3 zeng huiqing 2011-07-20 22:14:35 PDT
Created attachment 101557 [details]
newPatch

new patch
now pass the test animations/animation-end-event-short-iterations.html
Comment 4 Dean Jackson 2011-07-21 08:23:07 PDT
Comment on attachment 101557 [details]
newPatch

View in context: https://bugs.webkit.org/attachment.cgi?id=101557&action=review

In general I don't like that this adds the parameter to setAnimatableStyle. Is there way the RenderObject can know if it is attached to the tree so that we don't have to pass the flag around? From a brief investigation this path is only hit when the RenderObject is not in the render tree (it shouldn't have a parent) - is this correct?

> Source/WebCore/ChangeLog:3
> +        [Bug 64851][chromium]Optimize AnimationController::updateAnimations

You should give this a better title. There is no need for [Bug 64851] and this isn't specific to [chromium].

> Source/WebCore/ChangeLog:7
> +

Similarly, you should put a description here of what the problem was and what you fixed.

> Source/WebCore/page/animation/AnimationController.cpp:479
> +PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* renderer, RenderStyle* newStyle, bool InAttach)

The parameter name is pretty unclear to me. It should describe what it is doing within the function itself, not what the caller is using it for. Does that make sense? I mean that it should be something like timerShouldUpdate because that's how the updateAnimations function is using it.

Also, a style issue, the parameter name should not start with an uppercase character.
Comment 5 Simon Fraser (smfr) 2011-07-21 08:41:33 PDT
Comment on attachment 101557 [details]
newPatch

View in context: https://bugs.webkit.org/attachment.cgi?id=101557&action=review

> Source/WebCore/dom/NodeRenderingContext.cpp:287
> +    newRenderer->setAnimatableStyle(m_context.releaseStyle(), true); // setAnimatableStyle() can depend on renderer() already being set.

We try to avoid boolean parameters because they are hard to read at the call site, like this. Enums are preferred.
Comment 6 zeng huiqing 2011-07-21 17:52:43 PDT
Many thanks for helping review the patch and the good comments:)

> In general I don't like that this adds the parameter to setAnimatableStyle. Is there way the RenderObject can know if it is attached to the tree so that we don't have to pass the flag around? From a brief investigation this path is only hit when the RenderObject is not in the render tree (it shouldn't have a parent) - is this correct?


Through debugging, I found there exist another two call paths for RenderObject::setAnimatableStyle():
1)
WebKitClientImpl::DoTimeout()->ThreadTimers::sharedTimerFiredInternal()->Timer<AnimationControllerPrivate>::fired()->AnimationControllerPrivate::animationTimerFired()->AnimationControllerPrivate::updateAnimationTimer()[or AnimationControllerPrivate::fireEventsAndUpdateStyle]->Document::updateStyleIfNeeded()->Element::recalcStyle()->Node::setRenderStyle()->RenderObject::setAnimatableStyle()

2)
StyleElement::createSheet()->...->Document::styleSelectorChanged()->Element::recalcStyle()->Node::setRenderStyle()->RenderObject::setAnimatableStyle()

These two call paths both happen before "Attach", and I am sorry I am not sure whether can remove updateAnimationTimer() in these two paths when loading page w/ only transition property, so I add parameter to setAnimatableStyle().

And through profiling, we can find that the function AnimationController::updateAnimationTimer() doing in the process of "Attach" will consume a lot of time when loading page w/ transition property, especially when the page has many RenderObjects w/ transition property.

I will update the patch according to your good comments, thank you very much:).
Comment 7 zeng huiqing 2011-07-21 22:06:41 PDT
> These two call paths both happen before "Attach", and I am sorry I am not sure whether can remove updateAnimationTimer() in these two paths when loading page w/ only transition property, so I add parameter to setAnimatableStyle().

Sorry for the wrong comments, these two call paths both happen after "Attach", like ':hover' or ':active' will invoke these two call path, so add parameter to setAnimatableStyle() to judge whether or not to invoke updateAnimationTimer().
Comment 8 zeng huiqing 2011-07-22 01:27:00 PDT
Created attachment 101705 [details]
newPatch

use 'renderer->parent()' in function updateAnimations() to avoid calling updateAnimationTimer in the process of "attached" when loading page with only CSS3 transition property but no animation property.
Comment 9 zeng huiqing 2011-07-22 08:18:02 PDT
Can anyone possibly help review the patch? Thanks very much:)
Comment 10 zeng huiqing 2011-07-25 07:58:08 PDT
For page loading test, find that if load a page w/ CSS3 transition property, especially when page contains many RenderObjects w/ transition property, FF4 performs ~5.5X faster than Chromium&Safari.

Through analysis, find that the root cause is that w/ transition property, when a dom element is attached, it will call RenderObject::setAnimatableStyle, then AnimationController::updateAnimations, and it will call AnimationController::updateAnimationTimer, which is the hotspot.

And, in my opinion, we may do not need to call updateAnimationTimer() in the process of "Attach" when loading page w/ only CSS3 transition property actually.

Had submit a patch,use 'renderer->parent()' in function updateAnimations() to avoid calling updateAnimationTimer() in the process of "attached" when loading page with only CSS3 transition property but no animation property.
The patch will reduce page(with transition property) loading time by 70%, improve the performance by 3.3X.

Could someone possibly help review the patch when have a moment? Thanks very much:)
Comment 11 Dean Jackson 2011-07-29 01:56:28 PDT
Comment on attachment 101705 [details]
newPatch

View in context: https://bugs.webkit.org/attachment.cgi?id=101705&action=review

You'll have to wait until an official reviewer gives the r+. The two most familiar with the animation code are Simon and Chris, who are on vacation until Monday. I will try to find someone sooner.

Otherwise, this looks good. Thanks!

> Source/WebCore/ChangeLog:3
> +        Fix for bug 64851 - No need to call updateAnimationTimer() in the process of "Attach" when loading page with only CSS3 transition property but no animation property.

I think the title here should be "Avoid calling animation timer updates while the page is loading"

> Source/WebCore/ChangeLog:8
> +        No new tests. 

... and then here you should describe the change. For example:

There is no need to update the animation timer for a RenderObject that has not yet been inserted into the render tree, or that doesn't have animations. Our tests show that this improves page loading by up to 3x on pages with a large number of transitionable objects.
Comment 12 Dean Jackson 2011-07-29 01:59:33 PDT
Also, no need for "Fix for bug 64851 -" on the first line in the change log.
Comment 13 zeng huiqing 2011-07-29 03:21:25 PDT
(In reply to comment #12)
> Also, no need for "Fix for bug 64851 -" on the first line in the change log.

Dean, many thanks for helping review the patch and the good comments:)
I have submitted a new patch according to your comments:)
Comment 14 zeng huiqing 2011-07-29 03:23:18 PDT
Created attachment 102341 [details]
newPatch

change the style of ChangeLog
Comment 15 WebKit Review Bot 2011-07-29 10:23:52 PDT
Comment on attachment 102341 [details]
newPatch

Clearing flags on attachment: 102341

Committed r91999: <http://trac.webkit.org/changeset/91999>
Comment 16 WebKit Review Bot 2011-07-29 10:23:59 PDT
All reviewed patches have been landed.  Closing bug.
Comment 17 zeng huiqing 2011-07-29 16:32:30 PDT
Thanks very much for the review:)