In this session of the Angular Virtual Conference by Minko, we’ll look at the current state of Angular and its tooling infrastructure. We’ll discuss what features enabled the latest version of our rendering engine Ivy and how you can take advantage of them today. Along the way, we’ll look at the work we did to ensure small bundle size and fast execution! In the second part of the talk, we’ll focus on the tooling that Angular provides to help you deliver apps quickly and efficiently.
C# Corner - Global Community for Software and Data Developers
https://www.c-sharpcorner.com
Conference Website: https://www.2020twenty.net/angular
Show More Show Less View Video Transcript
0:00
All right. Okay. Yeah. Hello, everybody. My name is Minko Gechev, and I'm currently one
0:09
of the leads of Angular Developer Relations. Today in this presentation, I would want to
0:13
share with you what is the current state of Angular. This is going to be also kind of
0:18
a theoretical discussion as well. We will be talking about the reasoning for some of
0:23
the decisions that we have been making in Angular for a bit, for a while, actually, which
0:29
which could be considered quite different from where the rest of the ecosystem is
0:35
For example, we have been focused a lot on some static optimizations and static typing
0:39
like TypeScript and many other such features, which are bringing some specific benefits
0:46
when it comes down to development of Angular applications. Since I don't know how familiar you're all with Angular
0:55
I wanted to give you a very high-level overview on what we have been building, actually, in our team
1:01
Of course, we have a framework, right? We have Angular Core. It provides you with a bunch of primitives
1:07
that allow you to compose complicated user interfaces. You pretty much have here components
1:15
which can receive certain inputs, and they can also emit outputs. And on top of that, when you decide
1:22
that your source code wants to be more testable, you can take advantage of the Angular dependency injection
1:28
that comes together with Angular framework. We also have advanced content projection and many other features
1:35
but in order to get started with Angular, all you need to understand is just a component model
1:39
how you can create a component and how you can compose components together
1:43
On top of that, if you have been using the framework, you probably know that we have a pretty powerful CLI
1:49
It actually has pretty wide adoption, not only inside of Angular, but also in other frameworks out there as well
1:56
Together with the CLI, we're building components, the Angular Material Implementation, as well as the Angular CDK
2:04
All of them help you to quickly bootstrap your application. Of course, we cannot provide all the different components out there that exist
2:12
You can take advantage of them from community projects, but we provide a pretty solid core that allow you to quickly bootstrap your application
2:19
and know that these components work pretty well with the framework since they're developed by the same team
2:26
On top of that, we provide internationalization. This is actually a module and a mechanism, in fact, that I would want us to discuss a
2:34
bit harder in this presentation, because this is probably a pretty unusual implementation
2:39
of internationalization compared to all other implementations that you might have been used
2:45
to in other frameworks. So I would really want to spend some time discussing some of the reasoning of us behind it
2:51
This is going to be somewhere around the end of the presentation. We also have a language service, a router, animations, forms, and much more
3:00
And these are all maintained by the Angular team. So we have this right now
3:05
And to get here, well, it was a pretty long journey. I was lucky enough to be able to follow this journey, especially for Angular, since pretty much the beginning when I wrote my first Angular book
3:18
And it was pretty exciting for me to observe this from the perspective of a third-party contributor just contributing to a large, to a popular Google project
3:30
Now, later on, when I joined the team, I see how things are moving pretty fast
3:36
There are different requirements coming from the evolution of the web, coming from Angular engineers
3:42
and in general coming from the requirements of the business so that we can efficiently ship new features of business applications, right
3:49
That's our goal at the end. So the Angular framework itself, it went through very different paths
3:58
to be where it is today. I'm pretty happy and confident to share that right now
4:04
we're primarily focused on stability, making sure that we're addressing the issues
4:09
that we have been collecting on GitHub recently. We have quite a few of them to take care of
4:14
We're also investing a lot in simplicity. As you can see, we're constantly trying to reduce the conceptual overheads of folks who are getting started with the framework
4:23
And also, as usually, we're focused on speed. We want to provide the best and fastest change detection out there
4:30
We want to make sure that we enable best practices such as component level call splitting, route level call splitting, efficient prefetching, and so much more
4:39
Of course, at the same time, we have opened the space for innovation
4:43
This doesn't mean that Angular is now a mature project that is not going to grow from now on
4:48
Of course, it's going to grow. I'm going to talk particularly about this and how we're going to communicate our roadmap with community a little bit later in this presentation
4:59
So currently, we have over 2,000 projects inside of Google. To be exact, I believe the number is above 2,600
5:06
So for the past about 10 months, we got 600 new Google projects developed with Angular
5:17
And the current version of the framework is version 10. I'm going to talk about some of the features that version 10 introduced
5:25
But before that, let us discuss the theory behind the framework. I have mentioned this many times in many different presentations, but I'm really excited about compilers in general
5:35
I have this kind of academic interest in compilers and programming languages
5:40
So I really like to talk about the theoretical foundations, which are actually inspired to
5:47
a big extent by the compiler design, which we made in Angular
5:53
Often I prefer to start talking about these theoretical foundations in a very practical context
6:00
Next. You're probably all familiar with the tradeoff of predictability versus flexibility
6:07
A good example is the daily schedule of someone. Imagine you have a very booked calendar where you have optimized your schedule up to a minute
6:17
You know exactly when you're going to wake up. You know exactly when you're going to prepare your coffee and take it
6:23
You know exactly when you're going for a workout, going to the office and so on and so forth
6:27
This schedule could be a little bit stressful for a human. Of course, for a computer, this doesn't really matter
6:34
If you utilize the resources well, the computer is not going to be stressed out by having
6:38
a really well-optimized and strict schedule. But for a human, it could, and both for humans and for computers, it could be really hard
6:46
to introduce something new into the schedule, right? It's going to be really hard to introduce a new task since everything is already pre-booked
6:53
Your calendar is completely full. So you're very productive, but at the same time, not too flexible
7:02
Compared to flexibility, you can have your calendar completely empty. You might not be doing absolutely anything
7:09
And you could be potentially improvising every next day with what your schedule is going to look like
7:17
And this way, you're very flexible, but potentially not too efficient. In the context of programming languages and frameworks, this trade-off is better known as static versus dynamic
7:28
Static usually refers to operations that are performed ahead of time, at due time, during compilation
7:36
And dynamic are resources or tasks that are performed just in time, in the browser, at runtime
7:44
We can put some programming languages on this axis so that we can give you a better, like
7:50
intuition on what static versus dynamic means. My guess is that you're familiar with some of these programming languages, for example
7:58
with Rust. Rust is a pretty popular programming language coming from Mozilla right now
8:03
It has a really powerful, but at the same time, really static and really strict type
8:08
system, which doesn't allow us to do much. So if you try to, if we don't follow the constraint set by the compiler, we can, we will not be able to run our program at all because, well, it is not going to compile
8:23
But at the same time, this static and this like static behavior and strictness, it is helping for a very efficient memory management
8:32
On the other side of the spectrum, we have JavaScript. And JavaScript is a super dynamic language
8:38
With JavaScript we don really have to fight any compiler because we actually have zero compile time But at the same time we don have any guarantees that our program is even going to run in the browser
8:52
We get some runtime errors. And if our program starts growing, we don't know if we're going to catch these runtime
8:57
errors before shipping our program to production, right? So it could get quite tricky
9:03
We are sacrificing, in this case, stability and static verification and knowing that our program is going to work in general in the browser for better and faster prototyping with JavaScript
9:22
TypeScript is somewhere in the middle. So with TypeScript, we have a good type system, which can help us prevent a lot of issues ahead of time
9:29
But at the same time, it is not constraining as much. It is not restricting us too much to be expressive
9:36
and to be able to rapidly prototype new features. So I would say that TypeScript is really well positioned
9:43
into this spectrum from like static to dynamic. Of course, this still depends on the purpose of the language
9:50
I'm not saying that TypeScript is better than Rust. It very highly depends on the use case that you have
9:56
For example, with Rust, you can build really efficient and low-level systems, which you cannot build with TypeScript nowadays
10:04
It is also very interesting that from static, you can very easily go to dynamic
10:10
Imagine we have a very statically well-typed TypeScript program. We have very explicit type annotations
10:19
And, well, we're pretty confident that our program is going to run
10:24
and is going to work properly at runtime. Well, it's going to be very easy to make it more dynamic
10:31
It's going to be very easy to just drop some of these type annotations and get rid of the constraints coming from the compiler
10:37
and be able to start prototyping more, like, faster just by introducing new expressions with type any
10:45
or so on and so forth. But starting with a very dynamic program
10:50
with a JavaScript program, which has never been type checked before, it could be pretty tricky to make it static
10:57
and to add TypeScript type annotations. Not that it is impossible, it is just going to cost us a lot of work
11:05
If we put some more tangible features and associate them with static and dynamic
11:12
we can think about them the following way. For example, compile time optimizations
11:18
is something that static systems can provide. You might have noticed this in Angular
11:22
We have these static HTML templates, which are in fact translated to JavaScript
11:28
And they're translatable to JavaScript because they're static and the compiler understands them
11:34
ahead of time without having to execute the source code in the browser
11:39
So we can statically yze the templates and very efficiently translate them to JavaScript instructions
11:45
and make them really fast for execution. Angular, in fact, has been innovating a lot in this space in the past
11:52
If you're looking at the framework landscape, you can notice that Angular was probably the first framework
11:59
to introduce ahead-of-time computation. And you can see that this is now a common practice
12:04
and a lot of different folks found out that this is a quite powerful concept, right
12:08
Also, static systems allow us to have much better text editor and ID support
12:15
You can, again, compare TypeScript versus JavaScript. The TypeScript's types annotations provide much more context to text editors and IDs so that we can get good autocompletion
12:28
Strict type checking is something that I'm going to discuss just in a little bit so that I can give you kind of a tangible idea for the results that we're getting out of it
12:40
But on the other side, dynamic systems are not bad as well. Dynamic systems can allow us to perform very dynamic behavior
12:47
For example, we can even dynamically assemble the user interface. And the huge advantage of dynamic systems is that we don't have a build process there
12:57
So you can just put a bunch of scripts in the browser and everything is going to work
13:01
You don't really need to go through some kind of a build process that transforms your application to something else
13:12
So something that's like just a conclusion that I reached out several years ago
13:19
and I'm sure that I'm not the first person who have reached out to this conclusion, is that it's much better to get your errors ahead of time
13:26
during your build process instead of getting them at runtime when you have deployed your application
13:32
and you have shipped it to your users, right? So, of course, the best possible scenario is if we write bug-free programs, right
13:41
I was unfortunate enough to be able to create a large application
13:46
without having any issues in it. So if you are capable of doing this, you definitely don't need build systems
13:52
But if you're just like me, you probably can benefit from TypeScript type checking and from static systems
13:58
So here is an example which actually points out how beneficial TypeScript could be in your day-to-day development process
14:06
And when I'm saying TypeScript, I'm not necessarily meaning only TypeScript, since in Angular we have type checking in templates as well
14:15
So a couple of folks from community and from academia and Microsoft, they did a survey
14:21
They pretty much looked at different GitHub projects that were developed with JavaScript
14:26
They looked at their issue trackers and they tried to just verify which one of these issues was going to be detectable by the TypeScript type system at build time
14:40
They found out that 15% of the bugs were going to be detectable at build time instead of run time
14:47
So this means that these issues were never going to exist in the final product
14:51
So users would never have to go through the experience of hitting these issues
14:57
They would have never went through the experience reporting them. And developers never had to go through the process of fixing them
15:02
Imagine how much time this is going to save in a large organization working on a complicated project
15:08
And this survey was done with TypeScript 2.0. So this is TypeScript 2.0
15:15
Now we are in TypeScript's almost 4.0. It is coming in the next couple of weeks
15:20
It has much more powerful type system, and it helps us to catch many more issues ahead of time
15:26
Here is an example how static systems could be really powerful. I know that we usually associate dynamic with goods
15:34
but I just want to show you a different perspective how static could be helpful in letting you develop more high-quality products
15:44
All right. So talking about static and dynamic and putting them into the context of frameworks, AngularJS, this is the framework that Google released in 2009
15:55
It is very dynamic. It is on a very dynamic part of the spectrum
16:00
You can just take Angular, you can place it on a page, and you can start developing your program
16:06
You're not going to get any static verification by the build process. You're not going to get any type checking or whatsoever
16:11
But at the same time, you don't have any build process. So you were able to prototype very quickly and you didn't have to wait for your production build to complete, right
16:20
You were actually even able, if you want to, and if you want to live on the edge, pretty much develop your application in production environment
16:29
Why not? Angular version 2, however, started with a couple of things in mind
16:36
First thing was that static things and static checks are really useful
16:42
They provide better compile time optimizations, so they make the framework faster
16:48
They improve the text editor and ID support and also allow us to catch many more issues ahead of time
16:56
At the same time, the framework team also knew that if they start with a very dynamic framework
17:02
they would be really struggling to make it more static because they're going to break a lot of projects
17:08
So what they did back then when I wasn't part of the team They just made Angular version 2 really static, really constrained
17:15
You weren't able to declare... You had constraints on how you can declare providers, let's say, in your engine modules
17:21
You had a lot of different constraints, which were probably not necessary at the beginning
17:26
but that was a pretty good shot to make the framework static at first and from there grow it to a more dynamic solution which provides better development experience So that what they did For version four there was a rewrite of the compiler
17:40
and a rendering pipeline which made Angular more dynamic. With Ivy, we did one more such rewrite as well
17:50
So Ivy was this big project that we worked on for over two years, I'll say
17:55
This project took us a lot of effort because it was a really large rewrite of the internals of the framework
18:02
And you can't imagine what tiny things that you would have never expected
18:08
can have an impact on existing code bases have. So just like changing tiny internal piece in Angular can break hundreds of people
18:17
or even thousands of projects. So that's why it took us quite some time to make sure that Angular version 9
18:24
with Ivy was completely backward compatible with Vue Engine, which was our previous compilation
18:30
and rendering pipeline. So we made Angular more dynamic, but also not too dynamic so that we cannot take care
18:38
of all the compile time and static optimizations. Now, let me talk to you what is happening in version 10
18:46
That was a pretty long, I would say, overview of different trade-offs that we have in software engineering
18:58
Now, version 10 is a pretty small release when you look at it
19:02
We are pretty much providing an opt-in strict mode, and we're also aiming to increase more the visibility of what we have been building in the team to community
19:14
Now, I would want to talk a little bit about the second part
19:19
I would want to actually acknowledge the pretty rough feedback that we have been receiving over the past couple of weeks
19:28
Some of it was more constructive and reasonable than the other, but we definitely listened
19:34
You might have also noticed that we didn't share any public direct response
19:40
This doesn't mean that we didn't acknowledge and listen to everything. We have been, in fact, listening for quite some time, and we have had a plan on how we can increase the community engagement and be more open towards what we have been developing at the Angular team
19:56
So in the next couple of weeks, we'll be sharing some efforts
20:00
For example, we have been working on, like, actually over the past three months or so, on making our roadmap more digestible, not only by us, but also by folks who are outside of the team, outside of Google
20:12
so that we can all understand where Angular is heading to. We have been also working on opening some of our engineering processes
20:22
We would want to involve more people into the technical decision-making around Angular
20:27
so that you can provide early feedback on design decisions and just help us to shape the future of Angular and, in general, of web together
20:39
Remembering back when I was not part of the team, looking at the design decisions and the design documents for Angular, these were some of my
20:46
main resources that I was looking at, that I was reading through in order to understand the
20:51
framework and even understand many other technical areas where I didn't have expertise back then
20:56
Looking at the Angular source code and looking at the Angular's design documents, I understood how compilers work. And from there, I got really passionate
21:05
about them and started building my own programming languages. So I really think that this is
21:10
opening this design process is going to be not only helpful for everyone to understand where Angular is heading to
21:17
but also to grow together, get ideas from one another, and develop them
21:24
All right, now let us focus on the technical part of things. Now let us talk about Angular strict mode
21:32
The strict mode in Angular CLI version 10 is just a flack
21:37
It allows you to build applications with stricter configuration. This stricter configuration pretty much enables stricter type checking
21:50
So this helps you to catch more issues ahead of time. It enables stricter type checking for Angular templates as well
21:57
It makes the ECMAScript 5 support opt-in. This means that if you want to support Internet Explorer and you're in strict mode
22:06
you would have to enable this ES5 support. It also makes the CommonJS support opt-in
22:15
CommonJS is this module format that was originally developed for the server
22:19
for Node.js. And it got some traction for browser packages as well
22:25
which I wouldn't say is too reasonable. I'm going to show you an example of a CommonJS module
22:30
and how it can pretty much ruin your performance completely in a little bit
22:34
But if you would want to use common JS modules in the strict mode of the Angular CLI, well, you would not be able to unless you opt in into using it
22:44
And also with strict mode, we're assuming that your application has reduced side effects
22:50
This is pretty much taking advantage of the side effects property in package.json, which Webpack understands and applies more aggressive tree shaking on top of your applications when it finds this property and the setting
23:05
So the strict mode is not something that we're going to enable out of nowhere
23:10
This is something that is going to stay in the Angular CLI for a bit. We just want to get your feedback
23:14
We want to see how strict mode works for everybody. And if people really love it and they see actually noticeable improvements in their day-to-day development processes in terms of fewer issues or faster applications, we would want to just enable it by default for everyone
23:32
but if you find out that it is keeping you it is dragging you back
23:37
it is making you less productive because you need to fight with different static checks
23:41
and you would want to have more dynamic behavior we're going to just
23:46
remove it completely from the Angular CLI and preserve the current compilation pipeline
23:52
so see we still have this very interesting trade-off between static this makes the Angular CLI more static
23:59
with more compile time checks and dynamic, where we have fewer search checks
24:03
and potentially fewer optimizations ahead of time. Now, talking about more and stricter compile-time type checking
24:12
I'm sure that in your mind, you see something like this. A lot of folks, especially people who are just getting started
24:19
with software engineering, they kind of find out that they fight with both JavaScript and TypeScript
24:26
They get different errors, some of them in the browsers console and others in their terminal
24:35
And it's hard to understand the benefits of all this. Well, I hope that I give you just like a slight hint
24:41
that TypeScript giving you these errors just means that there is place for improvement
24:48
in your program so that you can reduce some of the potential issues that can occur at runtime
24:53
when you ship your application to production. Now, I would want to spend some time
24:59
talking about CommonJS because this is a pretty interesting problem and it again
25:04
shows the straight-off static versus dynamic. A couple of, actually over two months
25:10
ago now, yeah, I wrote this blog post about how CommonJS is making your bundles larger
25:16
I just wrote this blog post. This is a well-known fact. I didn't discover
25:20
it, but the findings in this blog post were pretty interesting. You can find it on
25:26
web.dev slash CommonJS larger bundles. Let us look at some examples so that we can understand why common JS is in fact making
25:35
your bundles smaller. Excuse me, bundles larger. So here we have a JavaScript program
25:43
We have a utils.js module which has a couple of public exports
25:48
So here you can see that we have an export of the at function
25:52
We're exporting subtract, multiply, divide, and max. It's interesting that we're importing max by
26:01
by low dash, and we're invoking it here. Just keep that in mind
26:08
At the same time, we have an index.js file, and in this index.js file
26:13
we importing only the at function from utils and we invoking it So here now we can take this program and pass it to Webpack
26:25
Webpack is going to produce a single JavaScript file out of these two modules
26:29
and this single JavaScript file is going to be highly optimized. Webpack is going to do everything it can to optimize it
26:37
so that it can be as small as possible to provide faster user experience for our end users
26:43
Once Webpack outputs this file, output.js, this file is going to be over 600 kilobytes
26:53
See almost like more than half a megabyte. See the original source code
26:57
In the original source code, we just have a couple of functions. These are for sure less than one kilobyte, right
27:06
And the final bundle is over 600 kilobytes. That was crazy. saw it, I saw that I did something wrong
27:14
So I spent a couple of iterations profiling what Webpack does, looking at the module loading
27:21
looking at the Webpack reports, and so on and so forth, until I realized that, well
27:26
that's just how things are. Here we're importing xby from lowvash, and since we're importing it with a common jess
27:36
require, it is getting part, like the entire load dash is getting part of our final bundle because, well
27:44
Webpack just cannot optimize common JS modules. I'm going to tell you why just in a little bit
27:50
Now, when we translate this to ECMAScript modules instead, here, see we are exporting the adds, subtracts
27:59
multiply and divide functions as well. We're also exporting max and importing
28:03
Again, Maxpy from Lodash, yes. Pretty much the same program. But instead of using CommonJS, we're using ECMAScript modules
28:12
The output after we bundle this with Webpack is going to be this. Pretty small, right
28:18
Pretty tiny. And depending on the configuration of the JavaScript optimizer Terser, this one plus two could be actually folded to three
28:28
So you can get two bytes less. This is 40 bytes compared to 625 QB, right? That's a massive difference. So you can see how a single
28:42
common JEST module can completely blow up your application size and make it much slower compared
28:48
to just using ES modules. And the difference is only in this. See only the UQS modules is slightly
28:58
different on how we are exporting things. The interesting thing here is that it is again related to this tradeoff static versus dynamic
29:08
It may not seem that command.js is much more dynamic, but look at this
29:14
Here we can export a function with a name that we're getting from local storage by touching
29:20
the element in local storage associated with a random number that we have generated
29:28
So this is extremely dynamic. Pretty much webpack at build time, it has no idea how to understand what is the module
29:34
name so that it can get rid of the export if we're not using it
29:41
This local storage get item information is something that is only available at runtime
29:47
Although at build time, statically, we have no idea how to optimize it
29:53
This is just one example. But I also want to give you one more example, which is related to the Angular's internal utilization
30:00
I have been hearing a lot of very mixed feedback about internal utilization. And a lot of people have been asking for a runtime internal utilization, which allows
30:08
you to swap the language dynamically without refreshing the page. And originally, actually, I thought that we just don't communicate the reasons why we have taken certain decisions on improving the internal initialization with static ysis
30:31
So let me share why we're doing it right now. by using our internal initialization
30:41
you would first compile your Angular application to JavaScript here for all your internal initialization markers
30:49
where we have specified the I18N attribute we're going to add some specific other markers
30:55
using our $localize service later on for each one of your translation files
31:06
we're going to take your application and apply direct replacements to the source code
31:12
So we're going to replace these markers that we introduced with the actual strings
31:17
associated with the particular translation that you're building your application with. So this means that with like four different translation files
31:24
you're going to come up with four different versions of your application. I want to address a couple of things here, first of all
31:32
So there were problems with our internalization in version 8 and before, where we had to compile your application once for each individual language that you support
31:42
And this wasn't ideal for sure. This was taking a lot of time. Now we optimize this
31:47
So instead of compiling your application once for each language, now we're compiling it only once
31:52
And we're performing replacements, depending on the language that you're targeting right now
31:57
Replacements are much faster than the original compilation. So that's why the build process now with like 100 different languages, it's not going to be so much different from the compilation process with one language, right
32:12
We're going to produce 100 different versions of your application as well, but we are no longer having to introduce like individual bindings for the different translations that you depend on, since we're going to replace these bindings with strings associated with the corresponding language
32:30
This is going to allow us to remove the runtime overhead associated with these bindings
32:38
since a binding means that Angular needs to perform checking there, right
32:43
Angular needs to verify whether the current value of the binding is different from the previous value, right
32:47
So this means that by performing this compile time I18, we're making your application much faster compared to binding to the individual translations one by one
32:58
Also, we're making it much smaller because each binding is a JavaScript instruction
33:05
And this JavaScript instruction adds up, especially when your application grows. So we're going to have smaller application and faster at runtime just by performing such static optimizations
33:17
And the cost for this is pretty much zero. The cost is that it's going to be impossible in this case to change the language without refreshing the page
33:28
And, well, to be honest, users are not usually changing from one language to another in a series
33:34
just so that they can read your content in, like, all the different languages that you provide
33:40
So this is not a very common use case. You're giving up something small in order to add
33:45
better performance to your application. So this is a way we implement internalization
33:51
It is much different compared to what most other frameworks do right now
33:56
I'm not saying that this is not possible to achieve in other frameworks. This is just a decision that we took
34:02
and it is a result of the design that we have for Angular. Static templates allow us to perform static optimizations
34:08
and produce faster applications. All right, that was pretty much everything I actually wanted to share with you today
34:17
I really hope that with this overview on static versus dynamic, I was able to point you to some of the motivation
34:25
behind the technical decisions that we made in Angular. I'm also hoping that I gave you a little bit more visibility
34:31
on what community processes that we're working on. For example, sharing our roadmap finally
34:37
and requesting for comments for some of the technical decisions that we're making
34:44
If you have any feedback for my talk or for myself or for Angular
34:48
feel free to reach out on Twitter. I'm responding there pretty actively
34:52
I spent far too much time on Twitter. And I would also really love your feedback on mgv.io slash talk about this presentation


