Using $templateCache in AngularJS

Angular uses templates as the View part of their MVC design pattern. Templates allow to prepare the html context of where data from the controllers will be displayed.

Templates can be used as partials for the whole ng-view based on the routing configuration, as well as for a directive to create components, or on the fly as a simple ng-include.

There are multiple ways to declare a template to be chosen from. The choice usually depends on how readable such presentation is.

directly as a text block:

angular.directive('cartItem', function() {
  return {
    template: '<strong>Name:</strong>  <strong>Price:</strong> '
  };
});

as an inline script:

<script type="text/ng-template" id="cartItemTemplate">
     <p><strong>Name:</strong> </p>
     <p><strong>Price :</strong> </p>
</script>
<div ng-include="cartItemTemplate"></div>

as a remote url to an html file:

<div class="cart-item">
    <p><strong>Name:</strong> </p>
    <p><strong>Price :</strong> </p>
</div>
<div ng-include="'cartItem.tpl.html'"></div>

Introducing the $templateCache

Using many template files is a good way to organize the application code and separate the reusable parts in a clear structure. It comes however at a cost of multiple http requests needed to render a single page. This can slow down the performance considerably.

One way of combatting the surplus requests is the $templateCache.

$templateCache is angular’s build in key-value store for the template contents. When fetching a template declared by a remote url through ng-include or templateUrl, angular looks for it first in the $templateCache and if the template is found there it doesn’t perform the http request. Templates can be placed and fetched from the templateCache by simple put and get functions:

angular.module('myApp', []) .run(function($templateCache) {
  $templateCache.put('cartItem.tpl.html', '<strong>Name:</strong>  <strong>Price:</strong> ');
});
$templateCache.get('cartItem.tpl.html')

Automating template caching

Puting everything in the templateCache manually would bring us back to the first inline solution, with poor readability and it would make changing anything in a template a thankless task. Luckilly there are grunt and gulp plugins that enable autogenerating the templateCache in the build brocess.

gulp-angular-templatecache

var templateCache = require('gulp-angular-templatecache');

gulp.task('prepare:templates', function () {
    return gulp.src('app/**/*.tpl.html')
        .pipe(ngTemplates({
            filename: 'templates.js',
            module: 'myApp',
        }))
        .pipe(gulp.dest('dist'));
})

The above task reads all the *.tpl.html files for the application and compiles them into templates.js file which then can be included in the app.

window.app.run(["$templateCache", function($templateCache) {
	$templateCache.put("CompanyChoice/CompanyChoice.tpl.html","<div>escaped contents</div>");
	$templateCache.put("CompanyChoice/CompanyDescription.tpl.html","<div>escaped contents</div>");
	}
]);

The process can be optimized further by singling out the critical templates which have to be served immidiately and lazy prefetching all the rest.