In this post I will discuss an experiment where I set out to create the smallest Angular application possible using Angular 4-rc.5.
Right now the most promising size reduction approach is using the Closure compiler. Closure is still experimental, but you can get a Closure compiled app down to about 34k.
I wanted to see if it's possible to reduce this even further. As a fun experiment I decided to act as a human Closure compiler and start cutting code from the Angular framework.
The experiment is not really more sophisticated than taking a hammer to the Angular framework until you're left with a sufficiently small application.
It may seem pointless to manually tweak the Angular source code. This may be true, but I think it's interesting since it gives an early indication of a theoretical lower boundary for application size.
I don't think I have found the lower boundary, but after a series of cuts I ended up with a 16.6k Angular application.
The application is very basic, but it supports data-binding and change detection. I have deployed a demo here. If you click the button you will see that the app updates a counter displayed on the button.
Take a look at the source map explorer for my app here.
In addition to tweaking the Angular code I also made a few tweaks to the rxjs source. I identified a few unused code paths and removed a few kilo bytes here as well.
My approach here is of course impractical and difficult to repeat since it relies on manual edits to the Angular source. At least it shows that you can stand up a basic Angular app with less than 25k of code. Technically you have to add about 10k of zone.js, but still, size is way down.
I have previously stated that Angular is only an appropriate choice if you are building large applications. I said this because the fixed cost of the framework is relatively high. In smaller apps this fixed cost is harder to accept than in larger applications.
At this point I might have to walk back this claim as I think Angular will eventually be able to deliver sizes comparable to small data-binding libraries. One example is KnockoutJS with a total size of 25k.
I think it's possible to reduce the size even more since I am still brining in large amounts of Angular code in my bundle. I decided to stop at 16.6k, mainly because it becomes very tedious at this point. Once you clear out the “big ticket” items, further optimization is a slow process.
My approach is also somewhat unrealistic since my code removal strategy is very aggressive. I also have the luxury of being able to run my code after every major code removal. An automated code removal process will have to be more conservative.
It seems possible to get an application down to about 20k using the Closure compiler.
There is probably room for improvements in the way the Angular source code is structured though.
Currently the Angular team is hand coding “static” framework files. Classes with multiple methods are included in their entirety, even if the app only needs one of the methods.
The Closure compiler helps optimize this though since it is able to remove unused methods and flatten/inline methods. I wonder though if this is happening too late in the process.
Perhaps the Angular team could benefit from making Closure inspired optimizations part of the original ngc compilation. Right now AoT is mainly focused on html views, but I see potential for extending this to the rest of the code base.
Instead of bringing in “canned” framework files, maybe the compiler could bring in code at the method level instead. This way you only bring in what's needed to run the application. I think this would make Angular even more of a compiler framework than it already is. It would be a big change to the current code structure though.
Svelte is an example of a “pure” compiler framework where the “framework” is created at compile time. Angular AoT is similar to this, but Svelte code is always much smaller.
I think Angular could potentially match Svelte if the framework code was added in a more targeted fashion. Instead of including fixed framework files, the compiler could include relevant code at the method level.
I wrote the commenting feature for my blog using Svelte. Even though this component is much more substantial than my tiny Angular sample, the total size is only 4.7k.
You can read more about this experiment here.
Even though AoT in Angular is based on a similar principle, I still think there is room for improvement.