How do custom templates/directives affect load times? - angularjs

I just learned how to create custom directives with angular today via codeschool and it is fantastic! The way it taught me was to make a directive in my JS file, link it to an html file, then write the tag accordingly in the index.html file which is my main file.
My question is does creating a whole new html file for a custom directive hurt load times on the main page? If you want a reference to the section I'm in, it is shaping up with angular level 4 (custom directives).

It depends on whether or not you precompile the templates directly into your main.js or not.
If you precompile them, your main.js will take longer to load, but, when rendering the view, angular won't need to send an http request to get the template so rendering will happen faster.
If you don't precompile them, the up front load time will be faster, but rendering the view may be slower the first time because angular needs to send an http request to get the template for the first time. after the first load, it will be cached in the template cache.
You could also use a hybrid solution, precompiling things needed for the main entry to your app, and letting angular request the rest as needed.
which one is better is a debate not suited for stackoverflow.

Related

$templateCache, ng-template and caching issues - angularjs

I am trying to cache my angularjs application's html files, following this suggestion: https://gist.github.com/ProLoser/6181026.
I am appending a dynamic cache key like ?v=123456790 to all html files (except those in the templates directory used by angular ui bootstrap).
For partials in their own files, i.e. app/views/customer/customer-history.html this works perfectly. However, for partials in script form, e.g. <script type='text/ng-template' id='customer-history'> the template is not found and a server request is made, resulting in a 404.
E.g. localhost:8080/customer-history/?v=1234567890
I can see the templates in question are in the $templateCache. The ones using ng-template are just the name ie customer-history whereas the separate files ones are by path app/views/customer/customer-history.html as you might expect.
It's a large app so going through and moving them all to their own files etc would not be trivial. I've scoured everywhere and I'm not turning anything up so I'm guessing it's something basic with how the templateCache is implemented.
I'm using gulp-templatecache plugin during the build process but the docs are quite limited and I don't think the issue lies there.
My current solution is just to skip the offending templates for now in the function appending the version number by decorating an inCache function onto the $templateCache factory and using it during the check to append the cacheKey. But I feel this is kind of missing the point.
Answering my own question here.
Because the script tags are part of the containing html file that gets loaded into the $templateCache, the script is already there. When a request is made for the templateUrl, it shouldn't have the cache busting appendix.
The simplest way to avoid all this is to just set the cache busting hash or string on the "templates.js", or whatever the template output of the build process is. That way the entire file gets invalidated and reloaded as needed.

Angular app with modular html files

I am writting an app from scratch in Angular with node.js and I was wondering if I am doing things correctly.
I want to split the content of my index into smaller html modules with their respective controllers, this way, everything will look more structured and easy to find when the project gets bigger.
For example :
index.html <--- main file
/views/menu.html <--- menu module
/views/content.html
/js/menu.js <---controller for the html module
/js/content.js
...
I can manage those files by just adding ng-include :
e.g
< ng-include src=" 'views/menu.html' ">
My concern is that this is like a GET request per file and I was wondering if this would affect the load speed of my application. Because I am working in local, this loads in 2ms which is very quick but I was wondering how this would behave online.
My questions are :
Is this the best way to create a modular app with different html files and js controllers ?
Is there a better way to achieve what I want to do ?
I am still learning Angular, sorry if this is too basic.
Thanks
Its better to use index.html as basic load file which will load all css and js on the load of the app,
for ex:- you can make diffrent app for login and after login section. After login.
load all the js and css files through the app after login..it will improve the loading time and also be a modular
as suggested by #Dhruv Raj Singh It is good to use a different ng-app for pre-login and post-login.
It is always good to structure the code that you want.
Now ng-include
will Emitted event $includeContentRequested every time the ngInclude content is requested.
Now it up to the requirement use cases how to use and when to use.
If
the module is a sperate and special one which requires lots of resources specific to it only and will be used by few users and only few times then it is better to include them for that module only
else common resources should be included at ng-app level.
You can name and organised the resources whatever way you want but include them at post-login app creation.

Sails.js and Angular.js project structure and configuration for non-SPA case

I am starting a side-project based in Sails to try it. Most of the pages are server-side rendered via EJS and don't require javascript on the front-end (my landing page doesn't, my "about" page certainly doesn't etc). However, I have a few pages that have quite a lot client-side functionality and I want to use Angular, because I am mostly familiar with that framework. The routing to these pages is again handled in the server and there's really no meaning in bundling them as a SPA.
So I am trying to wrap my mind around these concerns:
Where to place the Angular app's scripts?
Is /assets/js/dependencies still the proper place? Wouldn't placing them there make the Grunt task inject them in layout.ejs and thus in every page?
How to conditionally load the Angular base and it's components (controllers, services, etc)?
Sails uses views/layout.ejs as a base layout for loading project-wide styles, templates and scripts. Each page's controller handles injecting the body part into this layout according to the view "partial" that has been developed for that page. Is this view "partial" .ejs file the appropriate place to conditionally load the Angular app files in only the pages that require them?
How to add min/conctact/uglify of Angular' script sources in Grunt tasking?
All the Angular related files will need to be concatenated, minified/uglified for production. This will need to be a new js concatenated file to be loaded in appropriate pages apart from the "generic" js file that currently Sails tasks create and is loaded in every page. So we're essentially talking about two concatenated js files for the client side. One that is globally loaded, and the Angular one that only the pages that need it load. Which parts of the build/tasking procedure will require modifications? Some examples or resources to check would be highly useful here.
Where to place the Angular app's scripts?
Is /assets/js/dependencies still the proper place?
No, just put your angular.min.js in your dependencies folder, but not your Angular app's script. You need to put all you Angular app in the assets/js folder ( or in a sub-folder, but not in dependencies )
To be sure that each file of your app will be loaded in the right order (for example you need to load first the Js file which inject your angular app's dependencies), you can modify the tasks/pipeline.js file, and specify the order you want : You need to modify the jsFilesToInject array which contains all the Js files to load in the right order.
For example for your project :
var jsFilesToInject = [
// Load sails.io before everything else
'js/dependencies/sails.io.js',
// loading angularJS
'js/dependencies/angular.min.js',
// all the rest in dependencies
'js/dependencies/**/*.js',
// loading first AngularModule definition
'js/app/app.module.js',
// all the rest of the angular application
'js/app/**/*.js'
];
For your other question I think you need to look at the tasks/config/sails-linker.js file, that inject all the Js scripts in the <!--SCRIPTS--> tags in your HTML code.
I hope that it will help you and that I'm not too late !

how prevent angular compile specify element

I'm developing a chrome extension using angularjs (with a content script open a popup),but it meet some problem when it's parent page already use angularjs, it's parent try to compile the content inserted, so is there anyway to prevent the parent angularjs instance to compile the element I added, and the angularjs instance in extension can bootstrap the element manually ?
It's hard to answer without an example, or what is your extension flow.
Basically, angular shouldn't compile anything on it's own, it either does it when bootstrapping the app, or when you explicitly tell it to.
What I guess you are doing is have the html change before angular is loaded, and then when it loads it compiles your stuff as well.
Try adding your directives etc. after angular has finished loading on the main page (how to detect that angular finished bootstrapping is a whole other question :)).
And after you add your new element with your ng-app <div ng-app="myAngularExtensionApp"></div>, however I am not sure how it will work if it's nested inside another angular application, I don't think it will allow you to do it. If the ng-app of the main application is on the body you can add your div outside the body (weird, but legit), and it shouldn't conflict. but if it's on the html it might cause problems. (I tested it, you can bootstrap another one inside an existing app, but it can cause some really weird problems, I'd avoid it).
A bullet proof solution, that makes things a little more complicated is one I used and I like it alot:
Create an iframe on the page, which you add the angularJS script inside, and it will be your application, do not set the src of the iframe, but rather use iframe.document.open() .write(
<html><body ng-app="myExtensionApp"> etc (i.e. a complete bone structure of an angular page), now since the src is the same, you won't have same origin problems, and you can access the main page with top.
I recommend having services that will interact with the main page.
I am not sure what you want to do, but if you want a directive on the main page for example, first create it in the iframe, then move it to the main page via jquery, it will belong to YOUR angular application (since scope binding is based on prototype and the chain doesn't get broken by moving the element), it will keep reacting to changes to your scope.
However you have to remember that styles are unaffected etc.

Using Angular with Play: Role for Scala Templates?

When I first looked at Play and went through all the samples, I was pretty excited by the zentasks sample and the fluid, clean, effortless Javascript routing that left the work of rendering things to Play. But we decided instead to go with Angular.
Upon going down that road, I thought that Angular would control all aspects of rendering.
However, we have a page that has to get a socket. We were having the socket made on the server, so for now, we still have a Play (Scala) template doing that. We have pared it down to pretty much nothing: create the socket and then inject it into the Angular context.
But we are also trying to do Protractor tests and that is made uglier by having to figure out how to accommodate the Scala template.
Question: should we just ditch the scala template and have the Angular controller call the server and get the socket? That was my favored approach to begin with.
I'm currently working on two Play apps with Angular and in both we decided to have one single main.scala.html file that load all the necessary controllers,services,directives, etc from angular using of require.js.
The goal with Angular is to create a single page app and therefore you should avoid to mix it with server side templates.
You must see your main.scala.html template as the entry point of your single page application. There you generate and load all the pieces you need and give the hand to angular to manage the rest.
I agree with Renato. It's probably better to have a single controller and template that sets up the single page app with angular. Then use AJAX to send requests from the browser to other controllers (see http://www.playframework.com/documentation/2.2.x/JavaJsonRequests).
If want to to avoid Scala templates completely, you can put your web pages and javascript in the public directory and only use AJAX.

Resources