Optimizing Angular Application Using Template Cache

In one of my projects we were experiencing lot of server calls for the HTML files which we optimized it using Angular Template Cache and in this post I will showcase a thin example of our problem and how Angular Template Cache solved it using a Cache object.

As creating an application is not a part of this post, I already created angular-grunt-example which is an angular application with Grunt as a JavaScript task runner and available for clone from GitHub.

In an image below, one can see a server call each time we access .jsp file:

all-calls

to avoid all these server calls we will be implementing angular template cache, following below steps:

Step 1: Install grunt-html2js Grunt plugin with npm, as follows:

npm install grunt-html2js --save-dev

Above command will add grunt-html2js as devDependencies in package.json.

Step 2: Create html2js Grunt task in Gruntfile:

html2js: {
	  options: {
		base: 'src',
		module: 'myapp.template',
		singleModule: true,
		useStrict: true,
		htmlmin: {
		  collapseBooleanAttributes: true,
		  collapseWhitespace: true,
		  removeAttributeQuotes: true,
		  removeComments: true,
		  removeEmptyAttributes: true,
		  removeRedundantAttributes: true,
		  removeScriptTypeAttributes: true,
		  removeStyleLinkTypeAttributes: true
		},
		rename: function (url) {
				return url.replace('main/webapp/', '');
		}
	  },
	  main: {
		src: ['/pages/**/*.jsp'],
		dest: '/scripts/template.js'
	  }
}

module option specified above is the angular module name.

rename option specified above is used to make file paths match up exactly same as called from application, for example in application we are accessing .jsp pages as ‘pages/page-posts.jsp’, ‘pages/page-posts-list.jsp’ and ‘pages/page-authors.jsp’, etc and the file path generated is ​main/webapp/pages/angular-material.jsp`, so replace function strip ​main/webapp/ from each template path to produce a module identifier for the template.

Step 3: Load html2js task from the grunt-html2js Grunt plugin:

grunt.loadNpmTasks('grunt-html2js');

Step 4: Register html2js task with default task of grunt, so that when we run “default” task “uglify:dist” and “html2js” tasks run automatically, as follows:

grunt.registerTask('default', ['uglify:dist', 'html2js']);

On running the default task, template.js will be created in /webapp/scripts/ directory as a result of html2js task execution.

Step 5: Load tempalte.js generated by the html2js task as the first script after Angular and all related dependencies are loaded, as follows:

<spring:url value="/js/jquery-2.2.3.min.js" var="jQueryUrl"
<spring:url value="/js/angular.min.js" var="angularJsUrl"
<spring:url value="/scripts/template.js" var="templateJsUrl"
<spring:url value="/js/application.js" var="applicationJsUrl"

Step 6: Make myapp.template as the first dependency for the application module:

var myapp = angular.module('myapp', [ 'myapp.template', 'ui.router' ]);

Once done, browsing the application will not make call to the server for the .jsp files instead it fetch it from $templateCache which is a Cache object defined in template.js, as shown in the below image:

cache-calls.png

The complete source code is hosted on github.

Advertisements