
What is grunt?
Grunt is a JavaScript task runner based on Node.js
Think of it as a Makefile, but for JavaScript web apps.

Why use grunt?
- It automates mundane tasks for web apps through plugins such as:
- Compiling SASS and LESS files
- Unit testing
- Module loading via Require.js
- Uglification
- And many more!
- Customizable
- There's a large open source community
Why use Grunt with Zensey?
= ??

+

We are a design-driven company
We bring a unique experience to our clients through visually pleasing features



What does that mean?
There's a greater emphasis on browsers to render features through HTML5, CSS 3, and JavaScript.

But there's a problem...
-
Our HTML templates continue to grow as we add more DOM elements. Specifically <script> tags to import JS code.
- JavaScript code starts to get cluttered and harder to maintain.
- Adding more CSS classes increases the size of our CSS files, which creates a longer load time.
too many script tags!!!
Each script tag which points to a JavaScript file is a separate HTTP request.

profile/index.html
Angularjs
AngularJS helps developers modularize their JS code , but at the cost of separating out modules by files.

** Note that it's not necessary to modularize by files, but it was easier to navigate our JS code base.
Quirks Of angularjs
- You have to add the String literal dependencies when declaring your dependencies.
- Why?
- Because minification would rename the parameters, which then AngularJS would not know what service it's using.
angular.module('myApp') .controller(['$scope', '$location', 'barService', 'fooService', function($scope, $location, barService, fooService) {//something happens...}]);
Grunt to the rescue!
Let Grunt do the injection of string dependencies for you!
Developers can write their Angular components as:
angular.module('myApp') .controller(function($scope, $location, barService, fooService) {//something happens...});
And the ng-min task will do the rest:
angular.module('myApp') .controller(['$scope', '$location', 'barService', 'fooService', function($scope, $location, barService, fooService) {//something happens...}]);
Quirks of Angularjs (cont)
-
The concept of controllers, directives, services, modules, and templates can be confusing when developing a large scale app like Zensey.
- We separated each AngularJS component into it's own separate folder and file.

More scripts Tags??!!

base.html ..... NOOooOOoo!!!!!
Grunt to the rescue!
Because Grunt is a task runner, it can basically do whatever you want for your web application.
The Usemin Grunt task plugin by the Yeoman team seems to do the trick!

Profile
Before Grunt
<!-- build:js /scripts/profile.js --> <script src="/scripts/feed/activityFeed.js"></script> <script src="/scripts/feed/controllers/feedController.js"></script> <script src="/scripts/feed/controllers/post-activity.js"></script> <script src="/scripts/feed/directives/add-link.js"></script> <script src="/scripts/feed/directives/comment-ui.js"></script> <script src="/scripts/feed/directives/toggle-comments.js"></script> <script src="/scripts/feed/filters/twoDecimals.js"></script> <script src="/scripts/feed/filters/replaceSpaces.js"></script> <script src="/scripts/profile/connect-button.js"></script> <script src="/scripts/profile/zen.profile.js"></script> <script src="/scripts/profile/controllers/AchievementPodCtrl.js"></script> <script src="/scripts/profile/controllers/AchievementsCtrl.js"></script> <script src="/scripts/profile/controllers/AdminCtrl.js"></script> <script src="/scripts/profile/controllers/ConnectionsCtrl.js"></script> <script src="/scripts/profile/controllers/DeactivateCtrl.js"></script><!-- endbuild -->
Profile
After running the usemin Grunt task
<script src="/scripts/profile.js"></script>Other cool things Grunt provide?
- Uglify (minification)
- Our old minifier was fragile. Needed to always specify type="text/javascript" in the <script> tags or the JS file would not get minified
- Applying hashes to minified JS and CSS files (grunt-rev)
- Concating files (CSS and JS)
- Unit Testing via Karma
- Compiling SASS files
REsults
Dashboard


Production: 69 HTTP requests with avg. 2.26 s load time
Staging (Grunt): 19 HTTP requests with avg. 1.87 s load time
Results
Paths


Production: 61 HTTP requests with avg. 1.76 s load time
Staging (Grunt): 19 HTTP requests with avg. 1.28 s time
Results
Profile (when cache was cleared)


Production: 77 HTTP requests in 7.23 s
Staging: 21 HTTP requests in 3.14 s
There's still more work to be done
We cut our HTTP requests by 3x and load time by an average of .5 seconds depending on the feature, but there's still a lot of things we can do to improve our site.
- Leverage browsing caching through response headers (https://developers.google.com/speed/docs/best-practices/caching)
- Use AngularJS template caching
- Minify CSS
- Integrate Unit Testing
Questions?
Grunt
By Bryan Lin
Grunt
- 1,279