
Improving Angular 2 Load Times and a 29KB Hello World App
James Judd
Reading time: about 8 min

The Problem
When we released the beta of the Angular 2 version of our editor, we consistently saw load times about four seconds slower than our old editor.
The Solution
The Angular team built two tools to use TypeScript with the Closure Compiler: Tsickle and Clutz. Tsickle produces Closure annotated JavaScript from TypeScript, and Clutz produces TypeScript definition files from Closure annotated JavaScript. Together, they enable you to use TypeScript in a Closure compatible codebase, and vice versa. At Lucid, we modified Angular 2, its dependencies, and the AoT compiler in order to produce Closure compatible JavaScript from Angular 2 TypeScript. The end result is a five second improvement in load time for our new editor.



How We Did It
In this section and the next, we discuss what we did to make this happen and provide an example, in case you would like to reproduce our efforts. For those who want to skip straight to the example, you can find it here: https://github.com/lucidsoftware/closure-typescript-exampleTsickle
Tsickle is a project from the Angular team that produces Closure compatible JavaScript from TypeScript. It wraps the TypeScript Compiler and uses the TypeScript Compiler API to add Closure compatible annotations to TypeScript, compiles TypeScript to JavaScript, and converts CommonJS modules to goog.modules. You can use Tsickle to create TypeScript dependencies in your Closure JavaScript codebase. Tsickle transforms something like this:import Statement from 'goog:Statement';
export class Greeter {
constructor(public statement: Statement) {}
greet(): string {
return this.statement.getStatement();
}
};
Into this:
goog.module('js.app.ts.greeter');var module = module || {id: 'js/app/ts/greeter.js'};
class Greeter {
/**
* @param {?} statement
*/
constructor(statement) {
this.statement = statement;
}
/**
* @return {?}
*/
greet() {
return this.statement.getStatement();
}
static _tsickle_typeAnnotationsHelper() {
/** @type {?} */
Greeter.prototype.statement;
}
}
exports.Greeter = Greeter;
;
//# sourceMappingURL=greeter.js.map
Clutz
Clutz is a project from the Angular team that produces TypeScript definition files from Closure compatible Javascript. It uses the Closure Compiler’s API mode and performs a full closure compilation in order to produce a definition file that lets you use all your existing Closure JavaScript in a TypeScript project. Symbols or modules from your Closure JavaScript are available in TypeScript under the "goog:" prefix. For example, if you had "goog.provide('lucid.model.CustomShape');" in your JavaScript, you could import it in TypeScript using "import CustomShapeModel from 'goog:lucid.model.CustomShape';" Clutz can be used to turn something like this:goog.provide('Statement');
/**
* @constructor
* @param {string} statement
*/
var Statement = function(statement) {
/** @private {string} */
this.statement = statement;
}
/**
* @return {string}
*/
Statement.prototype.getStatement = function() {
return this.statement;
}
/**
* @param {string} statement
* @return {string}
*/
Statement.prototype.setStatement = function(statement) {
this.statement = statement;
}
Into this:
declare namespace ಠ_ಠ.clutz {
class Statement extends Statement_Instance {
}
class Statement_Instance {
private noStructuralTyping_: any;
constructor (statement : string ) ;
getStatement ( ) : string ;
setStatement (statement : string ) : string ;
}
}
Putting it All Together
Using Tsickle and Clutz, we modified our build system to support TypeScript dependencies in JavaScript and vice versa. It works like this: TypeScript and JavaScript build targets can mark other build targets as dependencies. Those build targets are then built, using either Tsickle or Clutz, depending on the type of dependency.
The 29 KB Hello World App
Lucid built a proof of concept Hello World Angular 2 application using Tsickle and Clutz before we tried implementing the same thing in our large JavaScript codebase. You can find the example on GitHub at https://github.com/lucidsoftware/closure-typescript-example. The purpose of the project is to provide an example of Tsickle, Clutz, and Angular 2 working together. Things are built from source, so you can see how we go from modified Angular 2 all the way to the final product. Comments, questions, and pull requests are welcome. When we compress the resulting bundle using Brotli, the final bundle size is right around 29KB. gzip is not far behind:$ ll --block-size=KB -rw-rw-r-- 1 james james 115kB Sep 27 02:45 main.js -rw------- 1 james james 29kB Sep 27 02:45 main.js.brotli-11 -rw-rw-r-- 1 james james 35kB Sep 27 02:45 main.js.gz
How to Run the Example
More information can be found in the example’s README, but to run the example, either:1. Docker
docker pull jjudd/closure-typescript-example docker run -t -i -p 8000:8000 --net=host jjudd/closure-typescript-example localhost:8000/index.html?compiled=1
2. Build it Yourself
make runNote: You will need to make sure you have all the dependencies installed for this to work. It has only been tested on Ubuntu 14.04.
About Lucid
Lucid Software is the leader in visual collaboration and work acceleration, helping teams see and build the future by turning ideas into reality. Its products include the Lucid Visual Collaboration Suite (Lucidchart and Lucidspark) and airfocus. The Lucid Visual Collaboration Suite, combined with powerful accelerators for business agility, cloud, and process transformation, empowers organizations to streamline work, foster alignment, and drive business transformation at scale. airfocus, an AI-powered product management and roadmapping platform, extends these capabilities by helping teams prioritize work, define product strategy, and align execution with business goals. The most used work acceleration platform by the Fortune 500, Lucid's solutions are trusted by more than 100 million users across enterprises worldwide, including Google, GE, and NBC Universal. Lucid partners with leaders such as Google, Atlassian, and Microsoft, and has received numerous awards for its products, growth, and workplace culture.