I've done a lot towards optimisation of one part of my application, due to huge amount of elements in DOM. I implemented lazy loading, watched for every digest cycle to be as small as possible, etc.
Now my question is, if anyone else has encountered, that the initial compiling and rendering is slower than rendering for the second time(like navigate to different app location and back again).
Is angular caching somehow and if so, how can I force to cache it in advance?
$Routing in angular is done using $templateRequest which in turn utilizes $templateCache. That's why all consequent template changes looks faster.
Tools like gulp-angular on yeoman.io for example automatically will build your application and place your HTML files in the $templateCache for you. It will also concatenate and minify all of the scripts.
Ultimately what you are looking for is for the html snippets to be all included in that single javascript file so that there arent individual HTML GET requests for each one.
Related
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
The application I'm developing uses "angular.js" + "ui-router" + "bootstrap". Many states and nested views. There are also some images related to templates and, finally, animated transitions placed there to generate feeling of fluidity.
Under ideal network conditions, the application works reasonably well.
Under poor network conditions, it is bad. Sometimes animation flicks, sometimes there is a pause between the user action and the response of the interface. (for instance: the start of an animation). The feeling of flow can not be achieved.
The problems are noted when "ui-router" changes its state, the application seems to lock or flicks animations or there are sudden jumps.
The application is to be used from devices with limited bandwidth due to its geographical location.
Can I preload all or part of the application, including images and others assets?
You can concatenate and minify all JS & CSS assets (if you are not already doing so). I use grunt-neuter for dependency management. You can also bundle all the dependent libraries together (I use grunt-usemin).
I have not tried to bundle all the templates into one file, but that should also be possible. In that case, you would wrap each template within <script type="text/template"></script> blocks, have everything in DOM, and pluck out individual templates and provide to each route. This should totally eliminate flicker.
For image assets, there are grunt plugins such as grunt-spritefiles that takes a bunch of images, and create a sprite, which then can be used within your CSS.
These are some of the techniques I can think of. However, the above can significantly increase the first time load. It may be acceptable for the use case you are describing. Hope this helps!
Currently our templates are in html files, while the build does minify them (with htmlmin)
It appears there are two approaches to optimize templates loading in angular.
using $templateCache as explained here. Which means putting the minified templates into a js file, probably with this grunt plugin.
Inlining the template,which means using them with angular script directive, probably using this grunt plugin
from npm usage stats I can judge that the first option is more popular, but I'm not sure why, what are the tradeoffs between the two options and which gives better performance.
Thanks!
To say anything more about performance it would have to be measured. But from the theoretical point of view (1) should be more performant since with (2) templates are ending in the $templateCache anyways, and using the <script> directive means additionally:
* having those <scripts> in the DOM tree
* processing <scripts> tags during the DOM compilation with this directive:
https://github.com/angular/angular.js/blob/master/src/ng/directive/script.js
In short: it looks like using <scripts> directive means more runtime processing in a browser. Should be confirmed with some performance testing, but I would assume that one won't see dramatic performance difference.
I have read the AngularJS documentation doc page but I am still not clear on what exactly happens. How does the compiler run? I mean is the compiler a piece of Javascript that is triggered on page load to run and inspect the DOM. If that is the case then is there much overhead every time the page is loaded?
I also have read that you should never change the DOM inside your controller. Why is that and could someone give me a simple example of what I should not do.
You should do a walkthrough of the mobile phone tutorial on the site. The directions are clear and it will show you how to set up your app and where the proper code should be. As Arun said, DOM manipulation should be handled mainly in your directives. Controllers handle the logic, the template handles data binding and incorporates directives to accomplish DOM manipulation. As you work through the tutorial, you will start to see Angular as a different way of thinking.
As far as compilation goes, the index.html page is rendered, the scripts are then loaded, and then Angular gets to work looking for the attributes to include the view template based on the routing and controllers. The template is then parsed with variables bound and watched, and then displayed to the user. Of course, there is a slight delay, as you can see on http://builtwith.angularjs.org/ . On the top right, you see "75 neat things built with AngularJS". If you refresh the page, you notice 75 is replaced with a ? until the page loads (less than a second later). Honestly, unless your controllers and views are incredibly complex, rendering time will never be very long at all. Personal example, I am generating a reports page with 12 columns of data 144 rows long, by parsing and looping through a JSON object multiple times and running calculations and creating a new object, all in the controller when the template is called. The page appears blank for about a quarter of a second before the data appears, templated, formatted, and with the appropriate callbacks.
Again, try it out, see for yourself.
I made a simple app using backbone.js and require.js. Earlier i used to have just one index.html file and used to dynamically render/hide different views. Now with require.js, i still have index.html file but i have created separate html files for each of my four views in the app, and i put them all in templates folder. Main point is, these four html files don't have the <!DOCTYPE html></html> tags, just the <div> tags for the view.
I'm not sure this is the right way to do it using require.js. Should i integrate all html code into just one index.html and using <script> tags for templating?
You shouldn't put your templates into one big html file, require.js and Backbone.js are the perfect combination to have everything in highly flexible modules, loaded only when neccessary.
With only a few modules you may not notice their advantages, but trust me, if you write more complex, dynamically growing high speed web applications, you save yourself hours of debugging and refactoring, and your code will be very simple to read and modify.
You have several ways to handle templates with Backbone, e.x. this.$el.html( _.template(template, this.model.toJSON() )) if you loaded your template into a template variable.
It won't affect speed, templates are only a few kilobytes. Comparing to the fact that your page is likely to already load a dozen files(many icons, a few images, css-es, js-es) even without BB.js or Require.js and modules, a new few-kilobyte-big file will not be noticable. Also, you can cache templates after first load if you use Require.js to load them.
Depends...
Mostly I would separate them because it fells more organized and easier to maintain, but... if you have too many of them (lets call them "Tiles") it can make your site slow because you will be doing several server trips to draw the site, I've read somewhere that when the browser have to make more than 4 request HTTP at the same time you will be punished for it with a slower performance, I will try to find the source and post here.
If your tiles are always together, I think putting everything in a single HTML with is ok, so you can fetch all of them with a single HTTP request, but the down side is that when you update a single template the client side cache of all templates goes to hell.
Another solution is to have them in separate files so they are more organized and using a build tool you create a big minified template file that you use on production, but that will require some work.
So you got to find the best way for your site.
P.S:Are you using a templating mechanism ? I find them really helpful in this situations.