angular / angular.js

AngularJS - HTML enhanced for web apps!
https://angularjs.org
MIT License
58.9k stars 27.54k forks source link

ngAnimate 1.2.0-rc2 has performance impact #4011

Closed damrbaby closed 10 years ago

damrbaby commented 10 years ago

Just by including the ngAnimate module in my project (using latest code on master), I am seeing noticeable performance degradation that is especially visible on devices with slower processors like the iPod Touch 4g.

In my case an ngRepeat with around 50-100 items and no CSS transitions / animations takes what could be 2-3x longer to render on a mobile device with ngAnimate. I noticed that the performAnimation function is being called 50-100 times per digest (the number goes up or down depending on the number of items in the ngRepeat).

The animation code is being executed on all elements of directives that support animation whether or not there are actually CSS transitions / animations that apply to those elements, and it has a performance impact. For most animation-enabled directives it might not be a big deal but it is especially noticeable during the rendering and re-rending of items in an ngRepeat.

olostan commented 10 years ago

@matsko updated my project ( http://gamme.co ) with your code ( https://s3.amazonaws.com/angularjs-dev/resolved-ng-animate/build/angular.js ). For not didn't faced any problem for now.

matsko commented 10 years ago

@olostan @mzgol @the-machinist @brian-frichette Me and @damrbaby pair programmed and fixed the ng-leave bug. So now I'm just wrapping this up with other optimizations. This will be ready soon.

@olostan the bug fix closes the pre-rendering issue.

@the-machinist your code is also working with this fix.

matsko commented 10 years ago

OK I believe we're in a much better spot now. The fixes are done and the caching is in place. Try it out:

https://s3.amazonaws.com/angularjs-dev/ng-animate-boost/angular.js https://s3.amazonaws.com/angularjs-dev/ng-animate-boost/angular-animate.js https://s3.amazonaws.com/angularjs-dev/ng-animate-boost/angular-route.js

You can see the difference with the docs search. Try going to the "search the docs" filter and typing in something like "animate". You see it chug for a few seconds right? Try entering something and then deleting it (select and press backspace).

https://s3.amazonaws.com/angularjs-dev/ng-animate-slow/docs/index.html

Now compare that to:

https://s3.amazonaws.com/angularjs-dev/ng-animate-boost/docs/index.html

@mzgol here's the commit for the new code: https://github.com/matsko/angular.js/commit/3abd591c3f2242f3564d65146562eb41e22787ab

allenwyma commented 10 years ago

@matsko Is there still an issue with ngRepeat and ngClass? I may be experiencing this. By change I came across this thread. I'm NOT using animation, just ngRepeats nested inside of ngRepeats several times over, but I'm also using ngClass inside of these repeats, too.

allenwyma commented 10 years ago

Is this possibly related? I'm having a huge performance issue with nested ngRepeats #1534

matsko commented 10 years ago

@HangingClowns no this isn't related. Anything involving ngRepeat prior to ngAnimate being attached will only slow down ngAnimate. The ngRepeat module by itself (when ngAnimate isn't included into the application) will never attempt to perform any of the animation-related lookups. So what you have in the core is as fast as it could be. Looking closer at the thread it could be all the extra filtering and I18n work going on, but let's try not to mix that material in here.

bfricka commented 10 years ago

@matsko My apologies for not getting around to debugging this (ng/ngRoute v. 3abd591, ngAnimate v. 2ab6bbc). However, I have tested this on our app and we are still getting ng-leave issues where elements are not being removed properly. I'm going to send out a quick proposal to see if we can come to an arrangement for working w/ the OS community to improve the OS software we use (like Angular) even though we're under NDA.

It's frustrating. Barring that, I will find a way to debug this. Thanks for all your hard work.

bfricka commented 10 years ago

Update: I've got the go-ahead to be able to work w/ you guys to debug this ng-leave issue. Please let me know if you're available to do a WebEx / Hangout. @matsko I know you have me on your Skype (bfricka) so feel free to hit me up there.

bfricka commented 10 years ago

@matsko and I worked through this and found the source of the issue. We didn't have a ng-leave transition specifically set and we were inhereting a base transition value for the element. I'm still not sure why this wouldn't at least use the inherited transition-duration and then remove the element thereafter. However, adding the explicit ng-leave class resolved the issue.

matsko commented 10 years ago

So it turns out that @brian-frichette's ng-leave issue was just silently inherited transition bug which caused the animation to hang. I'll make sure to document about this.

@mzgol did you test out the code?

damrbaby commented 10 years ago

Woo hoo!

Latest code from @matsko fixes all of the performance issues I've been facing, even on slower mobile devices, to the point where adding ngAnimate has a negligible performance impact. Mainly combining ng-repeat with other directives (ng-class / ng-show / ng-hide) and having those directives as children of an ng-repeat no longer causes performance problems.

Thank you for all your hard work @matsko and I can finally start adding more animations to my project!

matsko commented 10 years ago

Yesssss! OK here is the latest angular.js JavaScript files if anyone (@mzgol I'm looking at you) wants to have a final check on their code:

https://s3.amazonaws.com/angularjs-dev/ng-animate-patched/angular.js https://s3.amazonaws.com/angularjs-dev/ng-animate-patched/angular-animate.js https://s3.amazonaws.com/angularjs-dev/ng-animate-patched/angular-route.js

@mzgol please check https://github.com/matsko/angular.js/commit/4de604555a02082211b7489d1d2967f16d3b4d2c

the-machinist commented 10 years ago

I tried the uploads (@matsko latest files from ng-animate-patched are in the js lib folder 1.2.rc2-x4).. it doesn't seem to take the old ng-view out -

screen shot 2013-10-09 at 7 39 20 pm

https://github.com/the-machinist/angular-test

Sorry - maybe I'm missing something? Thanks for your continuing support.

matsko commented 10 years ago

@the-machinist diggin' in.

matsko commented 10 years ago

@the-machinist your .ng-leave-active CSS code for the ngView element animation has no styles on it.

.slide-animation.ng-leave {
  -webkit-transition: all linear 400ms;
  -moz-transition: all linear 400ms;
  -ms-transition: all linear 400ms;
  transition: all linear 400ms;
  z-index: 1;
}
.slide-animation.ng-leave.ng-leave-active {
  z-index: 1;
}

This means that the transition never kicks off.

Add some style change to it to it:

.slide-animation.ng-leave.ng-leave-active {
  opacity:0;
}

For it to work.

I'm guessing this is like this since you only have one ngView animation so far and you possibly didn't add any styles to the ng-leave-active class and got mixed up with the ng-leave bugs.

the-machinist commented 10 years ago

OMG, I'm so sorry. Thanks @matsko - It works after a style is added to .ng-leave-active! :D

matsko commented 10 years ago

No worries. I'll remember to document this in a noticeable way.

mgol commented 10 years ago

@matsko No excessive reflows after applying your patch. :) (I mean: no reflows caused by ngAnimate, it seems angular-sanitize now causes some).

matsko commented 10 years ago

I thought this day would never come :) Alright it's time for a PR and some merging.

mgcrea commented 10 years ago

Congrats @matsko for the amazing job fixing this, I'm looking forward to dig down into animations again!

ajoslin commented 10 years ago

Thanks matsko! This is great :-)

Sent from my iPhone

On Oct 10, 2013, at 8:17 AM, Olivier Louvignes notifications@github.com wrote:

Congrats @matsko for the amazing job fixing this, I'm looking forward to dig down into animations again!

— Reply to this email directly or view it on GitHub.

mgol commented 10 years ago

Yup, great job, @matsko! \o/

deakster commented 10 years ago

I don't want to ruin the celebrations, but after swapping the latest files over from @matsko , it seems about half of the animations in my project no longer work (compared to RC2). I have been using ngAnimate pretty heavily throughout this project.

I will try to dig into this a bit more and recreate on a plunkr, but upon first inspection, it seems the animations that are not working are ones that are on elements that are within an ngView or ngInclude. In many cases, I have an ngRepeat that is inside an ngInclude which is inside of an ngView, and these certainly don't seem to be firing.

matsko commented 10 years ago

@deakster are these animations triggered during the change of the ngInclude / ngView? Because that's expected. Please provide a plunkr as this should be closed by tomorrow.

deakster commented 10 years ago

It is not just during change of ngInclude/ngView. The exact setup is ngView->ngInclude->ngRepeat, and the ngRepeat animations aren't firing even once things are added/remove after view/include page change. As a quick test, I copy and pasted the ngInclude contents into the view, so it is now just ngView->ngRepeat, and it still doesn't work.

Both the ngView and ngInclude are loading pages that have been preprocessed into $templateCache could it be anything to do with that? As I mentioned, all of this works in RC2.

In any case, I will try to extract this out into a plunkr ASAP.

deakster commented 10 years ago

Ok, I figured out the cause. The animations only seem to work now if you have a CSS transition property specifically targetting the ng-enter and ng-leave classes.

So you basically need a .item.ng-enter,.item.ng-leave { transition... }

Whereas I had the transition defined at the item's base selector as .item { transition... }, since I am re-using those transition parameters outside of ng-enter and ng-leave.

It's not a problem for me though, I can easily add in more specific transition parameters into each of the sub-classes.

Great job on the performance improvements!

matsko commented 10 years ago

Yes this is the expected behaviour and it is strictly enforced with this patch. Great job finding out what was going on.

And... back to rebasing for me :)

deakster commented 10 years ago

Yes, I think it is fair enough to enforce this, but it is a change from how RC2 worked, so just noting it here in case others come across the same issue.

joegaudet commented 10 years ago

How soon till this is available through normal channels ?

Our build all relies on bower.

.jo

On Thu, Oct 10, 2013 at 8:15 AM, deakster notifications@github.com wrote:

Yes, I think it is fair enough to enforce this, but it is a change from how RC2 worked, so just noting it here in case others come across the same issue.

— Reply to this email directly or view it on GitHubhttps://github.com/angular/angular.js/issues/4011#issuecomment-26062276 .

.joe out.

+1.778.994.4846

joegaudet commented 10 years ago

Oh yes and a big thanks !

On Thu, Oct 10, 2013 at 9:04 AM, Joe Gaudet joe@joegaudet.com wrote:

How soon till this is available through normal channels ?

Our build all relies on bower.

.jo

On Thu, Oct 10, 2013 at 8:15 AM, deakster notifications@github.comwrote:

Yes, I think it is fair enough to enforce this, but it is a change from how RC2 worked, so just noting it here in case others come across the same issue.

— Reply to this email directly or view it on GitHubhttps://github.com/angular/angular.js/issues/4011#issuecomment-26062276 .

.joe out.

+1.778.994.4846

.joe out.

+1.778.994.4846

matsko commented 10 years ago

Should be in master tomorrow.

Narretz commented 10 years ago

master is not in bower, though. This'll land in 1.2 RC3, I think.

mbelshe commented 10 years ago

@matsko - Just wanted to chime in and let you know that your test files definitely fixed my ngAnimate performance problem as well. Look forward to it landing! Thanks!

matsko commented 10 years ago

Happily landed as ddcbf7604af44e264aeeed75f1afb4a477a637fc

guillaume86 commented 10 years ago

@matsko could you specify what is exactly expected in css/dom to trigger animations with the last changes?

I have trouble restoring animations in this case (angular animate the entering/leaving, masonry the positionning): 1.1.5: http://jsfiddle.net/g/3SH7a/ 1.2.0-rc3: http://jsfiddle.net/g/3SH7a/45/

matsko commented 10 years ago

RC3 introduces a restriction on placing the transition on the base class. However, with RC4 (which is 1.2.0) this restriction is gone. So wait a few days until that's out to test your code against that.