Experimenting with the new Angular ivy renderer on windows

Mathias Raacke
5 min readDec 7, 2018

--

At the time of writing, the new Angular ivy renderer is 93.46% complete (according to https://is-angular-ivy-ready.firebaseapp.com/#/status).

Ivy is a complete rewrite of the Angular renderer (the part of angular that turns your component templates into actual dom nodes), and promises smaller bundle sizes and faster code. There is a great summary of Ivy features by Telerik, so if you don’t know ivy yet read that first. https://www.telerik.com/blogs/first-look-angular-ivy

I care a lot about performance and bundle size of my Angular applications. I actually even consider improving performance of my apps “fun” and spent a lot of my free time on experiments about performance and bundle size. Therefore I’m very excited about Ivy and wanted to see if it is now mature enough for some experiments.

So let’s just try it out. You can create a new ivy project by using Angular cli with the — experimental-ivy flag:

ng new hello-ivy --experimental-ivy

I use the default answers for all the stuff that “ng new” wants to know, so I don’t add routing and just use plain css.

To build the project with ivy, I run a production build with — prod:

ng build --prod

Unfurtonately, this just produces an error message:

ERROR in Child compilation failed:
Entry module not found: Error: Can't resolve 'C:\github\oocx\hello-ivy\C:\github\oocx\hello-ivy\src\app\app.component.html' in 'C:\github\oocx\hello-ivy':
Error: Can't resolve 'C:\github\oocx\hello-ivy\C:\github\oocx\hello-ivy\src\app\app.component.html' in 'C:\github\oocx\hello-ivy'

This looks like yet another problem related to Windows handling paths different than other operating systems. Unfortunately (for me as a windows developer), most people working on open source projects like Angular work in non-windows environments, don’t test on Windows and often don’t consider Windows related problems to be high priority.

A quick search on google confirms my suspicion. There is already a discussion and even a pull request in the Angular repo, though it does not look like it will be included anytime soon: https://github.com/angular/angular/pull/25862#discussion_r216157914

However, the discussion on github contains some clues on how I can easily fix the problem for me. After all, I don’t want to create anything for production, I just want to do some early experiments with Ivy.

So here is the fix:
Open node_modules\@angular\compiler-cli\src\ngtsc\annotations\src\component.js

In that file, there are several calls that use the posix version of path funcionts, like path.posix.resolve and path.posix.relative. Just remove the “.posix” part, so that it’s just path.resolve and path.relative.

After I modified the file, I try to compile again:

C:\github\oocx\hello-ivy (master -> origin)
λ ng build --prod
Date: 2018-12-07T11:32:40.200Z
Hash: 2a17df2f8f0cc1df78e3
Time: 17841ms
chunk {0} runtime.ec2944dd8b20ec099bf3.js (runtime) 1.41 kB [entry] [rendered]
chunk {1} main.c167e21775b8b7622c83.js (main) 41 kB [initial] [rendered]
chunk {2} polyfills.20ab2d163684112c2aba.js (polyfills) 37.5 kB [initial] [rendered]
chunk {3} styles.3ff695c00d717f2d2a11.css (styles) 0 bytes [initial] [rendered]

Great, this works for me. By the way, I’m on node 10.7.0. I don’t know if the fix also works on other versions of node, and I did not really investigate what the difference between the node default versions of path functions and their posix counterparts is (that’s something I will look into later).

So we now have a total script size of 81.775 bytes (uncompressed). About half of the size is for zone.js. In theory, you could built Angular apps without zone.js, though that would require a lot of manual change detection code.

How does that compare to a non-ivy project?

I created the same app again, just without ivy. The total script size for the non-ivy app is 218.260 bytes.

So the ivy hello world app is only about 37% of the bundle size compared to the old renderer. If you leave out zone.js and just compare main.js (after all, zone.js is not directly part of Angular), it’s 41 KB ivy vs. 174 KB for the old renderer, so ivy only needs about 24% of the original bundle size!

What does that mean for performance?

Let’s compare both apps. As “ng serve” does not seem to work with ivy yet, and also because it did not compress scripts well in some of my previous tests, I’m using local-web-server and run it in the dist folder to just serve the files generated by ng build.

I don’t want to get overly scientific with my test methodology, so I simply open the Chrome dev tools, check “disable cache” and reload the pages a few times. I then look at the results for the “finish” measure. What I get for the ivy app is:

96 ms, 99 ms, 102 ms, 99 ms, 97 ms.

The overall (compressed with gzip) script size is 28.3 KB.

I repeat the same results with network settings set to simulate “fast 3G”, to also compare the effects of using ivy for mobile users:

1.93 s, 1.93 s, 1.97 s, 1.95 s, 1.96 s

Then I run the same test for the non-ivy app:

133 ms, 140 ms, 167 ms, 132 ms, 133 ms.

The overall (compressed with gzip) script size is 63.4 KB.

I repeat the same results with network settings set to simulate “fast 3G”, to also compare the effects of using ivy for mobile users:

2.13 s, 2.16 s, 2.17 s, 2.17 s, 2.12 s

So on average, Ivy saves about 200 ms for a hello world app on “fast 3G”.

A hello world app is not representative for a real world application, so it would be interesting to see how Ivy can improve performance in more realistic scenarios. That will be something I’m going to cover in a future post.

However, even for a hello world app, it’s 200 ms that you get “for free” by simply updating to a newer version of Angular. So I’m really looking forward to the official release of Ivy.

--

--