I'm optimize my angular app. I found that only bootstrap the angular app will cost hundred milliseconds.
console.time("ng-boot");
angular.bootstrap("myapp");
console.time("ng-boot");
the time is nearly 300ms!!!
then I want to get all the running time of each controller(init) and directive(postLink maybe...), during the "bootstrap" phase. how can I achieve that?
of course I can get the time by adding logs in every controllers and link functions in directives. but I have too many directives. I want to know if there is a better way.
personally i suggest you use chrome developer tools, profiles tab.
it has great tools to check speed, memory, cpu. much better than console.log everywhere.
Related
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 :)
I am taking over a big (50+ modules) AngularJS project, from another programmer, which did not do it right, so I have several migration questions:
There are lots of usages of JS functions like setTimeout and setInterval. It will be very easy to change to $timeout and $interval (because they use the same syntax, so it is just find and replace), but should I bother?
The entire project is without services, and all data requests run in the controllerss. Should I make time to create services for all controllers, the most important ones, or none? (I know that "if it works dont fix it", but from your experience does this make your life easier?)
The ENTIRE project uses $.ajax, with over a thousand requests. I do not have the time to migrate all requests to use $http, but I will try over time. In the meanwhile, should I create a service like $http_o and replace all "$.ajax(" strings in all files to $http_o, so the service will pretty much get a normal ajax request syntax, and send it using the $http service.
Every controller's services are written in a variable name, and not with a string at the start (function($scope) instead of ['$scope', function($scope)). Is there a fast way to change all of them to use the normal syntax, so I can use a minifier, or do I have to do it by hand? Should I do it?
I will obviously try my best to rework modules to use correct MVC and angular rules in my spare time at work, but this will happen way ahead in the future.
It's not as trivial as you might think i.e. $interval applies a $rootScope.$apply() at end so it will trigger $digest cycle, with lots of intervals it might slow down app
It's all about readability and maintainability. I'd say yes, do separate services and DRY the application otherwise when you will have to debug it in 3 months time it's going to be hell
A smart regex could work for you although the advantage of using $http over $.ajax is that you don't have to use tricks to trigger change in view - i.e. manually run $digest or $apply
You can do it easily with https://github.com/olov/ng-annotate
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.
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
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.