ngUpgrade performance considerations - angularjs

I am trying to figure out if we can move our Angular 1 application to Angular 2. We have a sufficient amount of code to warrant using ng-upgrade as opposed to starting from scratch.
Our current application is pushing the performance limits of what Angular 1 is capable of. Hopefully Angular 2 will bring us some performance benefits.
My question is how much of an impact on performance our migration path will have (i.e. running Angular 1 alongside Angular 2 as per ng-upgrade guidelines)? Will it have a noticeable impact or will it not be noticeable in practice? My main concern during this period is run time speed as opposed to memory usage or load time.

Not sure if this thread is still relevant, I'll try to add some further notes. Currently we are at Angular 6, and the upgrade behavior has gotten a lot better.
For anyone having performance issues or thinking there might be issues I recommend have a look at the downgradeModule (https://angular.io/api/upgrade/static/downgradeModule#differences-with-upgrademodule)
You basically can either Upgrade the Angular 1 part or downgrade the Angular 2 part. On a first view they might seem similar but the behave fundamental differently. For anyone concerned with performance I definitely recommend the latter approach. This way you will have the improved performance for your new Angular 2 code and the old code runs at nearly the same/if not the same speed.
Even for fairly large applications it is a breeze and you very rarely have any performance problems.

You should know that there are two ways to bootstrap a Hybrid App:
UpgradeModule - bootstraps both the AngularJS (v1) and Angular (v6) frameworks in the Angular zone
DowngradeModule - bootstraps AngularJS outside of the Angular zone and keeps the two change detection systems separate.
I have tried both ways. And I recommend using DowngradeModule - it's better for performance and memory leaks.

I am currently in similar shoes and the only thing I know is that the digest cycles of A1 and A2 trigger each other. This makes me think that during upgrade, things will be slower... I will update you if I find anything different in coming months.
https://angular.io/docs/ts/latest/guide/upgrade.html#!#change-detection
Everything that happens in the application runs inside the Angular 2 zone. This is true whether the event originated in Angular 1 or Angular 2 code. The zone triggers Angular 2 change detection after every event.
The UpgradeModule will invoke the Angular 1 $rootScope.$apply() after every turn of the Angular zone. This also triggers Angular 1 change detection after every event.

Related

Migration to Angular2 -> advice required

Some background:
I having part in developing a huge, extremely dynamic and customizable Angular 1 web application.
Since it so huge and dynamic, there are tons of watchers out there - 4K in single view, at least.
As may be expected, the application is suffering from major performance problems. This huge amount of watchers make application loading and general response times to be very long.
As one possible solution, I was considering to upgrade several of "heavy" components to Angular2 - so these parts could live in ng2 framework and use ng2 change tracking - which is much faster.
While reading migration documentation, I noticed this paragraph:
When we downgrade an Angular 2 component and then use it from Angular 1, the component's inputs will be watched using Angular 1 change detection.
At this point I want to get advice, just to make sure I'm taking right decisions:
Since I not going to convert the whole application at once, but to convert incrementally (directive by directive), which direction I should take in order to benefit ng2 performance improvements (e.g. ng2 change tracking):
a. Should I migrate "bottom-up", e.g. top level components will
remain ng1; while lower level will be converted to ng2, or
b.
Migrate "from up to the bottom"
Personally I prefer first option (sounds to me less risky), but in case the shell will remine ng1 while its content will be converted to ng2 - isn't that means (according to documentation) that I will be forced to use ng1 change tracking mechanics inside ng2 components? Or I get it wrong?
From your experience, which migration direction proves itself better?
Thanks
So I'm a bit late to the party here. The ngUpgrade stuff by the Angular team is absolutely fantastic and a viable solution, however I think it'll create more work that perhaps it may be worth (depending on the size of your application).
What I'd shoot for would be a modular process of upgrading a single module at a time rather than components/services at a time. i.e. assuming your 1.x app is broken up into modules you can begin rewriting the first module for example a "dashboard" module or "inbox" module. I went through this process before and we rewrote the homepage of our application, and once the user needed to hit another page that was the "legacy code", the url had /v1/ in to show that they'd actually gone to another application. This way we technically had two applications but ran them completely separate.
If you're still looking at concepts etc to upgrade, I've been working on an Angular 1.x to Angular 2 migration guide which may help you on your way :)

ngUpgrade in production app/website?

We have an app/website using Angular 1.5. It'll take time to convert everything to Angular 2 and it isn't a priority as what we have currently work.
I was thinking it could be interesting for new components/directive/services to write them in Angular 2, to avoid having to eventually convert them later on, as well as to start learning the new syntax.
But is it really a good idea to ship something containing Angular 1.5 and 2 with ngUpgrade? The memory footprint should end up being bigger, but are there other drawbacks?
The following article http://blog.thoughtram.io/angular/2015/10/24/upgrading-apps-to-angular-2-using-ngupgrade.html by Pascal Precht mentions: Keep in mind that the goal of this [upgrade] phase is to stay in it as little as possible, since running both frameworks on the same website is surely not ideal. but that doesn't tell us much.
Does anyone have feedbacks with a "real" (ie not tiny or proof of concept) partial update using ngUpgrade?
We have a large commercial product (banking web-application) and we use a hybrid application on production.
We migrate services and components from AngularJS 1.5 to Angular 6, and it will take at least a half year.
A few tips:
To avoid all issues with $digest and performance I recommend using DowngradeModule - it bootstraps AngularJS outside of the Angular zone and keeps the two change detection systems separate.
The first hybrid app used UpgradeModule and we had a lot of problems, - this approach is not for large applications.
Use similar code before bootstrapModule(AppModule)
import { enableProdMode } from '#angular/core';
if (IS_PRODUCTION) {
enableProdMode();
}
If you have any questions - you are welcome.

Angular directives causing long load times

We currently have a large complex application build using Angular (1.3).
I have a page that is maybe using 20 custom directives (nested).
I'm finding the load time (angular bootstrap) is very slow especially on android.
Using chrome timeline profiling I can see the angular bootstrap is taking about 800ms on desktop, but about 8 seconds on android (using remote debug).
This is on a fairly new android phone (samsung s5). However on an iPhone 5 (it takes no more than 4 seconds.
My question is does directive compilation have to take that long? I don't think my directives link functions are actually taking long to execute. Will replacing directives withe a combination of ng-include/ng-controller make it better? Will replace 20 directives with one big directive make a difference?
Why would the mobile chrome browser be so less performant than iOS safari browser and very similiar hardware?
Thanks,
It is likely due to the high number of requests a browser makes to render your website. Each directive has a template, so that's 20 requests on top of all the others (js files, images, css etc). You also have to consider that each directive/template is loaded when its parent directive/template is loaded since they are nestled, and this can make a huge impact on performance.
It may also load faster on desktop and varies on mobile based on a browsers simultaneous connection limit. I believe for iOS safari it is 6, and mobile chrome is 4.
You need to reduce the amount of template loading, and ensure you are making use of a browsers cache. In your case it may be better to combine some directives to improve performance.
Your fisrt question
My question is does directive compilation have to take that long?
No. Angularjs can handle much more than 20 custom directives quickly according to my experience.
I don't think my directives link functions are actually taking long to execute.
I think you may run into issues and need to spend time on optimization probably. Maybe too much DOM manipulating or HTML reflow.
Your second question
Will replacing directives withe a combination of ng-include/ng-controller make it better?
I don't think so. ng-include/ng-controller are also directives. There is no essential difference.
Your third question
Will replace 20 directives with one big directive make a difference?
No. The number of directives doesn't matter. What matter is what directive does.
And your last question. It's a fact sucks and torments me long time. I also don't know why.

How do you figure out the bottle necks in an AngularJS app?

AngularJS batarang is unusable. It freezes and is unresponsive. How do you figure out where the bottlenecks are? What kind of tools can I use to profile my application to figure out if its my directives or if I have too many watchers?
This problem is perhaps caused, because you broke the watch-apply-digest cycle of the Angular framework by causing digest cycles where they should not be. This can cause Angular to create almost infinite loops watching variables for refresh, thus making your app really slow. But you can confirm that by just disabling Batarang, since the app would be slow by its own.
Anyway, if your app is efficient and only Batarang creates this issue, you can skip using it and start debugging with developer tools. I have also switched to this path various times and I can say it is quite fast (I did not expect it either). To follow this strategy, you have to simply select an element with developer tools and then execute in the JS console :
var scope = angular.element($0).scope()
So, you now have the scope of this element and you can simply check any field you want inside the scope at any time, thus testing the whole watch-apply-digest cycle of Angular.
You can learn more about the watch-apply-digest cycle here

Feasibility of using angular js for web app with over 200 medium to complex screens

My team was considering using angular js for web app UI development. But knowing at a high level how single page apps work, I had a question as to, how feasible it is to use angular js framework, for a large web application. this would have at least 200 screens, each screen containing an average of 30 UI controls like text boxes, calendar controls, drop downs etc.
The user will be accessing the web app on desktop or laptop and will be using the application in the browser throughout an 8 hour day, without ever closing the browser.
Given above usage, would angular js, memory usage / performance be issue?
are there web apps with huge and complex UI, built using angular js, that are in production and used everyday?
You can have not just 200 but 1000's of screens - this number does not matter as long as you address the core and fundamental questions below. They all boil down to memory and performance.
At a given point of time how many $watches will be active.
At a given point of time how many listeners are created.
At a given point of time what is the complexity of DOM i.e. the number of DOM elements and thee nesting/depth.
At a given point of time how many Javascript modules (services, controllers etc.) will be loaded in the memory. Even though these things are singletons they consume memory.
For each such screen how much memory will be consumed (if you use jqueryUI etc. your memory increases quite rapidly than pure angular + html components)
This brings to what you can do to control the above factors which if not watched will make your application sink/crash.
1) How do you break the run-time complexities of your "big" application ? You can now think of "Routers" or dialogs. Each of your screen will come-and-go i.e. you will never display 200 screens the same time.
2) Make sure when the screen is gone there is no "leftover". Don't use jQuery - if you do make sure you clean this on $scope.$destroy.
3) Multitudes of directives:- Directives are powerful but don't over use it - try not to deep nest too many of them. templateUrl is "tempting" but sometimes in-lining a template is the best choice. Use build tools that will inline the templates.
4) Load modules on demand using requireJS. This will force you to modularize your application and think hard about concatention strategy (combining JS files). Will force you to write independent modules.
5) Browser caching your assets and a good cache busting mechanism. Grunt based plugins are to your rescue. Minify your assets.
6) Compresss the assets for efficient network utilization and faster transmission.
7) Keep your app encapsulated in Angular. Don't create any global objects. Chances are that they have access to some closure or are referring to some things within angular $scope and $scopes are now still hanging on or are in difficult trajectory to be able to get Garbage Collected.
8) Use one-time-bind or bind-once model binding as much as possible.
9) Splash screen is an excellent weapon - us it. Helps you load some stuff upfront while the user watches smooth/jazzy picture/picture :)
Regarding 8 hours a day constant use
Unless there is a leak of the following kind you should be fine:-
1) Listeners leaking i.e. hanging around.
2) DOM leaks. Detached DOM issue.
3) Size of Javascript objects. Javascript objects coded in a certain way creates repeated instances of function.
(I am developing AngularJS app - with more than 450 screen - MDI like app. The app is not yet in production. The above points are coming from my burnouts in the functionality we have developed so far.)
I've worked on multiple projects that are extremely large single-page applications in Angular and Ember.JS at companies like McKesson an Netflix.
I can tell you for a fact that it's completely "feasible" to build "huge, complex" applications with frameworks such as Angular. In fact, I believe Angular is uniquely well suited to this because of it's modular structure.
One thing to consider when creating your Angular application is whether or not every user will benefit from all "200 pages" of your application. That is to say, is it necessary to have all 200 views be part of the same single page application? Or should you break it into a few single page applications with views that share concerns.
A few tips:
Watch out for name collisions in the IOC container: If you create enough services and controllers, even if you break them into separate modules, it's very easy to create two services with the same name. This may or may not result in an outright error. What happens when you register two "fooService" services? The last one wins.
If you decide to break your app into more than one single page app, you have to be sure you have solid boundaries of functionality between the two. They're not going to be able to share state easily other than with something like cookies or local storage.
If you decide to keep everything in one single page app, you're going to want to keenly watch your initial download time. Always check to see how long it takes to start your app "cold" over a slow-ish connection. If the entire app is in one bundle, depending on how you structure things (are you going to use AMD?) then you might see a long initial load time.
AVOID rendering HTML on your server. I can't stress this enough. Let Angular do that work for you. The only rendering your server should be doing is rendering JSON to be returned from some RESTful service.
Flush out your JS build process early on. Look into Node-based tools like Grunt, Gulp, and Broccoli for linting/concatenating/minifying your JS files. Checkout Karma for running unit tests, and look into Istanbul for code coverage. Protractor is a great tool as well, but I recommend strong unit tests in Karma over integration tests with Protractor just because Web Driver based tests tend to be brittle.
Other than that, I think you'll find a single page app written in any modern framework to be extremely snappy after the initial load is done. In fact, it will make any "old" PHP/ASP.Net style app that renders the entire page at the server seem slow as dirt in comparison. This is because you'll only be loading data and the occasional .html file over HTTP.

Resources