Angular Ivy migration, a contrasted feeling, this is not what we expected !
This article is a feedback of our Angular Ivy migration. It won’t be opinionated, but rather following a pragmatic method. We will detail the process, the breaking changes and the final measurements.
We started 3 years ago in Angular V4 (first article), the migration from V8 to V10 was definitely the most impacting and the most exciting !
A bit of context : what is our application ?
This is the funnel that allows the visitor to enter his personal information to apply for a loan.
We customize the experience and the translations for the each country, so we build 10 packages, one per country (France, Italy, Spain, Portugal, Germany) and per device type (desktop, mobile). As a result, we have a French desktop funnel, a French mobile funnel, an Italian desktop funnel, and so on.
The Funnel handles around 20K visitors per day. It brings a major part of the company revenue.
What did we expected from the migration ? Why migrate ?
The most important announced features of Angular V9 were :
🚀 Faster build times (with a more incremental compilation)
🔥 Smaller build sizes (with a generated code more compatible with tree-shaking)
🔓 Unlocking new potential features (fullTemplateTypeCheck, lazy loading of component instead of modules, new features for i18n)
🧪 Faster unit testing
When and How we Proceeded ?
We created a dedicated branch to start the update in April, to quickly identify any breaking changes. We dedicated up to 5 hours per week for this migration. We regularly merged the master branch into this branch to keep the latest updates.
In the end, it is only during summer holidays, with some team members in vacations, that we were able to focus on the migration for a whole week, without being disturbed with merging new features into the master branch.
- regression with i18n attribute on custom elements😥
The retrieval of the `i18n-xxx` attribute on a custom component is broken. The attribute value was null inside the custom component.
To fix this, we introduced a function
getI18nAttributeValuein the custom component. This function is called during
ngOnInit and it ensures that, at this life-cycle hook, the attribute is not null anymore.
In 9.0 version, Angular moved the build-time i18n substitutions later in the build process, which probably caused this regression.
- inner text is now mandatory🤔
In a template, we had :
With V10, the content of the span is not replaced by the translation value.
As a result, we are forced to put a text in the span :
Unit Testing : custom optimization is not required anymore !👌
Until Angular V9, for each component related unit test, the component was recompiled so we were spending ~75% of you time re-compiling components for testing purposes. So we were able to use this optimization to only reconfigure the current test suit to prevent angular components compilation after every test run.
Thanks to Angular V9, this optimization isn’t required anymore. It actually becomes harmful to keep it. TestBed does not recompile components between tests unless a component has been manually overridden, which allows it to avoid recompilation between the grand majority of tests.
No more custom Decorators 🤐
The custom decorators are not working using AoT and Ivy. So we had to find a dirtier solution for our decorators :
There is an open issue but even if a solution will be available soon, we already removed our decorators by implementing the logic in an abstract class.
We ran the application build several time to be able to obtain average features.
- Build Time 38% decrease 😀
- Unit test run time : 15% increase 😑
- total artifacts size (before gzip) 😶
V8 27.3 MB (feature modules : 928 KB)
V9 27.2 MB (feature modules : 785 KB)
We set up a scheduled cron job to run node lighthouse against the website to measure the end-user impact.
- speed index : no impact 😶
- time to interactive : 13,5 s to 12 s 😉
For our users there is no visible impact, but for us the build time improvements make a world of difference.
When using a framework like Angular, not following the version update is not an option if we want to ensure maintainability as the time passes, so no regret but we hope that the future will be brighter.
There is no magic. You can’t expect for huge improvements from a framework update, you always have to challenge yourself. For us, I am sure that the biggest improvement regarding build time will done on our side by migrating from an application built 10 times to a multi-tenant application. Thanks to the new i18n features, it will help to achieve this.