How to use Asp.Net’s built-in bundling and optimisation feature to optimise AngularJS templates.
A core feature of AngularJS is the ability to put HTML templates in partial template files, and have Angular load them on demand and add them to the DOM, as shown in the tutorial: Routing & Multiple Views.
For example, I could define a route so that when a user navigates to
#/investment/3, Angular loads the necessary template and renders the view with the associated controller like this:
Templates are an essential part of any large Single Page Application, since trying to put all the HTML in a single file is simply unworkable. Templates aren’t just limited to one-per-page, but can be used to define components within a page. This leads to another problem, which is that the page will have to make multiple server requests just to get the HTML content. For example, if my home page is a dashboard-style layout with five components, it has to make seven requests to get the HTML (one for the SPA container, one for the page template, then one each for the components).
I like to leave optimisation off in the debug and test versions, for easier debugging, but switch it on for the release build for performance. This is easily done with an AppSettings switch in web.config, as shown above.
~/bundles/application bundle is done like this:
In debug mode, the files are downloaded individually and are not minified for easy debugging:
In release mode, we get a single minified download instead:
Bundling Angular Templates
Angular has a
templateCache object, which stores all the templates it has loaded so far. It also lets you pre-load templates into the template cache, so that’s what we need to do. If we have a (very simple)
hello-world template that looks like this:
Then to insert it into the
Let’s look at that Process function. We start with the first line of the Angular module declaration, which needs a module name so we pass that into the constructor. Next, we loop through the list of files, read in the content of each one, and wrap it in a statement to insert it into the
templateCache. This code assumes that the templates are in the folder ‘partials/’. Finally we add the terminating line of the module declaration, and update the response object.
response.Files to an empty array, which means that no file links get rendered when optimisation is switched off (in debug mode we want to dynamically download partials as normal). We set
Now I have implemented a transform, I can use it in a custom Bundle:
Just like the built-in
StyleBundle, we derive from
Bundle, and use our new transform class. I’ve passed the name of the Angular module through as a parameter.
Now we can add the following line to
I’ve used the name of the main application module in my Angular application (“testSPA”). If we used a new module name, we’d need to add a dependency from the application module to it, so extending an existing module avoids that problem. We can include the bundle on the page like this
And that’s it. Now, when I open the application in debug mode, nothing is rendered by the
~/bundles/partials bundle, so Angular dynamically downloads the templates. When I open it in release mode, the bundle renders like this:
templateCache, so that Angular doesn’t need to dynamically download them.
Bundling and Optimisation are powerful features for improving the responsiveness of Asp.Net applications, without the need for a distribution build step. With a little extra effort, we’ve added Angular’s templates to that process, and optimised six requests for HTML content into just one download.