Eliminate render-blocking JavaScript and CSS in above-the-fold content (Angular JS Controllers) - angularjs

I am trying to optimize my page speed with me MEAN stack application. I have run into the issue where I should be eliminating the render-blocking Javascript and CSS. I have gotten to the point where I have almost eliminated everything, EXCEPT for the controllers that have to be loaded.
I am thinking that it is not possible to actually do this, since angular throws an injector module error when I place "async" as an attribute on the <script>.
I was also thinking of making one large controller, but that does not really work as well.
The link to the site is https://coastalreign.com, below is the code for the controllers:
<!-- ANGULAR CUSTOM -->
<script src="js/app.js"></script>
<script src="js/controllers/MainCtrl.js"></script>
<script src="js/controllers/ContactCtrl.js"></script>
<script src="js/controllers/ProductCtrl.js"></script>
<script src="js/controllers/ProductsCtrl.js"></script>
<script src="js/controllers/CartCtrl.js"></script>
<script src="js/controllers/TrackOrderCtrl.js"></script>
<script src="js/controllers/CheckoutCtrl.js"></script>
<script src="js/controllers/DesignerCtrl.js"></script>
<script src="js/controllers/SublimationCtrl.js"></script>
<script src="js/controllers/LocationCtrl.js"></script>
<script src="js/controllers/ServiceAreaCtrl.js"></script>
<script src="js/controllers/CategoriesCtrl.js"></script>
<script src="js/services/getCategoryText.js"></script>
<script src="js/controllers/CustomQuoteCtrl.js"></script>
<script src="js/controllers/GradContestCtrl.js"></script>
<script src="js/controllers/four04Ctrl.js"></script>
<script src="js/controllers/popularGroupingCtrl.js"></script>
Thank you in advance for your guy's expertise!

The problem is the amount of requests. I would bundle the JS files (app + vendor files) and minify them.
You can check for performance tips with Chrome - Developer tools - audits

You can use gulp-concat to reduce the amount of requests as Alexander's answer suggested. Then you can use gulp-minify to decrease the size of the file. You will have some additional issues if you want to put async option because you might need to render HTML which depends on angular

Related

How to load Angular UI Bootstrap and dependencies

I'm experimenting with the Angular UI Bootstrap libraries (specifically modal) but I'm having trouble getting the right versions of each library loaded in the right order, but I keep coming up against the No module: template/accordion/accordion-group.html error. I've switched back to Bootstrap 2.3 but it's still there. My application header is below, can anyone spot any wrong versions or JS files out of order? I'm also using Angular UI Sortable, hence its inclusion.
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="http://code.angularjs.org/1.0.2/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.4/ui-bootstrap-tpls.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.css">
<link rel="stylesheet" href="style.css" />
</head>
My app declaration looks like this:
var app = angular.module('myModule', ['ui', 'ui.bootstrap']);
Edit
I managed to get it working like this:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.11.2/ui-bootstrap-tpls.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-sortable/0.13.2/sortable.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.css">
<link rel="stylesheet" href="style.css" />
</head>
and
var app = angular.module('myModule', ['ui.sortable', 'ui.bootstrap']);
did you download all the files? according to their docs
Files to download
Build files for all directives are distributed in several flavours:
minified for production usage, un-minified for development, with or
without templates. All the options are described and can be downloaded
from here. It should be noted that the -tpls files contain the
templates bundled in JavaScript, while the regular version does not
contain the bundled templates. For more information, check out the FAQ
here and the README here.
Alternativelly, if you are only interested in a subset of directives,
you can create your own build.
Whichever method you choose the good news that the overall size of a
download is very small: <76kB for all directives (~20kB with gzip
compression!)
Looks like your error is with a template not begin available or loaded. Maybe you missed the download which packaged the templates. In your case the accordian template isn't being loaded.
After reading the FAQs I'm also wondering if having both angular-ui cdns is causing your problem. The angular-ui is loading first without templates and then your loading angular-ui-bootstrap with templates.
Angular-ui-bootstrap FAQ
This project comes with several deliverables described here:
https://github.com/angular-ui/bootstrap/tree/gh-pages#build-files If
the roles of those files are not clear for you just pick
ui-bootstrap-tpls-[version].min.js, but be sure to include only one
file in your project.
You're showing this
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.4/ui-bootstrap-tpls.min.js"></script>
Try just loading
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.4/ui-bootstrap-tpls.min.js"></script>
More info on the builds from github
the excerpt i'm reading is
Now it should be clear that files with the -tpls in their name have
bootstrap-specific templates bundled with directives. For people who
want to take all the directives and don't need to customize anything
the solution is to grab a file named
ui-bootstrap-tpls-[version].min.js. If, on the other hand default
templates are not what you need you could take
ui-bootstrap-[version].min.js and provide your own templates, taking
the default ones
(https://github.com/angular-ui/bootstrap/tree/master/template) as a
starting point.
Did you add 'ui.router' and 'ui.sortable' as dependency in your app.js file ?
var myApp = angular.module('myApp', ['ui.router','ui.sortable']);
I would use a package manager such as Bower or WebPack to manage your client side dependencies.
According to the Angular UI docs you only need to add:
AngularJS and Bootstrap CSS. No need for jQuery.
And then you should initialize your Angular App module with ui.bootstrap dependency:
angular.module('myModule', ['ui.bootstrap']);
== UPDATE
According to this example, this should be everything you need:
index.html
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
<script src="https://rawgithub.com/angular-ui/ui-sortable/master/src/sortable.js"></script>
```
app.js
var myapp = angular.module('sortableApp', ['ui.sortable']);
Let me know if this helps you

How to use complete AngularJS file in your program?

Up until now I was using links to minified AngularJS files in my code, but now there is a requirement because of which I have to use complete AngularJS file. I have downloaded it from the official site, and:
<script src="../Angular/angular.js"> </script>
<script src="../Angular/angular-animate.js"></script>
<script src="../Angular/angular-aria.js"></script>
<script src="../Angular/angular-cookies.js"></script>
<script src="Angular/angular-loader.js"></script>
<script src="../Angular/angular-message-format.js"></script>
<script src="../Angular/angular-messages.js"></script>
<script src="../Angular/angular-mocks.js"></script>
<script src="../Angular/angular-resource.js"></script>
<script src="../Angular/angular-route.js"></script>
<script src="../Angular/angular-sanitize.js"></script>
<script src="../Angular/angula-scenario.js"></script>
<script src="../Angular/angular-touch.js"></script>
and this is how I added all these files in my code, but it is not working, please let me know what is the correct way of using complete AngularJS file.
Your path for angular-loader is different from the rest of your paths. I'm not sure if any of them are correct. I'd recommend starting the Chrome developer tools and then going to the Network tab to see if all of your resources are loading correctly.
Looking at your codepen it appears that you are reloading the Angular libraries later in your HTML. That is probably causing Angular to reinstantiate and therefore destroying whatever you've done in your code in between. Try deleting or commenting out the lines where you load Angular from cloudflare.

How can I run React-router without the jsx transformer

I have a really basic app setup where I have the react lib and the router setup as global scripts and it seems that the Router requires the transformer to run. Is there any way that I can get it running without the transformer?
<script type="text/javascript" src="/js/vendor/react-with-addons.js"></script>
<script type="text/javascript" src="/js/vendor/JSXTransformer.js"></script>
<!-- if I remove the transformer then nothing is displayed on the page -->
<script type="text/javascript" src="/js/vendor/ReactRouter.min.js"></script>
Ok it seems that this was a user error. I had my main script setup as a jsx file :p
<script type="text/jsx" src="/js/dist/app.js"></script>
switching to a plain js did the trick!

How to add cordova to existing angular project

I've been searching high and low and couldn't get a direct answer or getting my code to work.
I have an existing Angular project that was started via yeoman with Angular and PhoneGap setup together. My setup uses yo and bower to generate the files.
I've tried to import certain cordova plugins to test out like the camera or datepicker and see if it works on the device but it doesn't as it was always saying the calling function is undefined.
So with the current setup I call the code below in one of my submodules
navigator.camera.getPicture(onSuccess,onFail,{sourceType:1,quality:60});
This doesn't work so I tried other tutorials and also by trying ngCordova which is a wrapper class for angular. The following is how it looks like in my index.html
<!-- build:js(.) scripts/vendor.js -->
<script src="phonegap.js"></script>
<!-- bower:js -->
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-animate/angular-animate.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="bower_components/collide/collide.js"></script>
<script src="bower_components/ionic/release/js/ionic.js"></script>
<script src="bower_components/ionic/release/js/ionic-angular.js"></script>
<script src="bower_components/json3/lib/json3.js"></script>
<script src="bower_components/angular-translate/angular-translate.js"></script>
<script src="bower_components/pouchdb/dist/pouchdb-nightly.js"></script>
<script src="bower_components/angular-pouchdb/angular-pouchdb.js"></script>
<script src="bower_components/proj4/dist/proj4.js"></script>
<script src="bower_components/ngCordova/dist/ng-cordova.js"></script>
<!-- endbower -->
In the tutorials it's asking to have the ng-cordova import above this line which does not exist
<script src="cordova.js"></script>
How do I generate this cordova.js into an existing project and will it conflict with the phonegap.js file?
Just create a new project, add a platform (e.g. ios) with cordova and put the cordova.js file of it into your existing project. Phonegap supports both phonegap.js and cordova.js as stated here. You'll find the file in platforms/ios/www/cordova.js. Then, you're right, the cordova.js has to be included as the last <script> that you include.

What is the difference between scripts/plugins.js and scripts/modules.js?

Yeoman built out my first angular app, and in the index.html, it placed the following code that I'm guessing will be consumed by some build process (I don't know what that process is yet.)
But in the index.html, it broke up the scripts between these 3 comment groups. The last one seems to be where my code goes, but the first 2 are somewhat arbitrary in their distinctions. I'm trying to figure out what they mean, so I know where to insert these pieces that I need to add to make the app usable:
<script src="bower_components/angular-ui-calendar/calendar.js"></script>
<script src="bower_components/ng-grid/ng-grid-2.0.7.min.js"></script>
Do they belong in the first group (build:js scripts/plugins.js) or the second (build:js scripts/modules.js)? And why are jquery and angular outside both of those groups. Feels like I need some kind of handle on what those directives do, but googling for build:js doesn't produce results that seem to be relevant.
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<!-- build:js scripts/plugins.js -->
<script src="bower_components/bootstrap-sass/js/bootstrap-affix.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-alert.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-dropdown.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-tooltip.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-modal.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-transition.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-button.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-popover.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-typeahead.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-carousel.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-scrollspy.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-collapse.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-tab.js"></script>
<!-- endbuild -->
<!-- build:js scripts/modules.js -->
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="bower_components/angular-cookies/angular-cookies.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
<!-- endbuild -->
<!-- build:js({.tmp,app}) scripts/scripts.js -->
<script src="scripts/app.js"></script>
<script src="scripts/controllers/main.js"></script>
<!-- endbuild -->
An explanation or pointers to the relevant docs would be very helpful.
Yeoman built out my first angular app, and in the index.html, it
placed the following code that I'm guessing will be consumed by some
build process (I don't know what that process is yet.)
The "build process" is grunt, but more specifically the grunt-usemin plugin is what will be using the directives inside the comment blocks in the index.html.
Do they belong in the first group (build:js scripts/plugins.js) or the
second (build:js scripts/modules.js)?
That's a decision for you to make. Keep in mind that all the scripts included within each block will get concatenated and minified into a single script include in the built version of the index.html file. The "build:js scripts/plugins.js" instruction is telling the grunt build system that this is a javascript block and to create a plugins.js from the result of concatenating and minifying the contents of the block.
And why are jquery and angular outside both of those groups?
You can group and categorize your scripts however you want, but there are some best practices. For instance, you may want to place all the scripts that are owned by you in one block since they may change frequently. This may help improve caching performance on the client since changes to your scripts should probably not cause all scripts to be re-downloaded. You probably wouldn't want to include jQuery and Angular scripts in the same block as your code because it would build a very large (monolithic) script that would have to be reloaded every time you update your code.
I typically organize my groups either by categories, such as 3rd party plugins, libraries, or modules. Sometimes, if performance is key, I may think about my groups in terms of how frequently I expect the scripts in each category to be updated, that way the user isn't being forced to download code that hasn't really changed.
Feels like I need some kind of handle on what those directives do, but
googling for build:js doesn't produce results that seem to be
relevant.
Read the docs at the grunt-usemin plugin page to learn all about how to use the "directives" you are seeing.
I think jQuery and Angular are outside because by default, grunt cdnify changes those paths to use Google's CDN.

Resources