The State of Angular


In this presentation, 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.


Hello everyone. My name is Miku Gelchev. I'm an engineer at the angular team at Google. Today, in this presentation, I would want to share with you what is the current state of angular. I know that this is a general javascript event rather than an angular-specific conference, so that's why I wanted to share a couple of words with you on what exactly our team at Google has been working on. Obviously, we're building a framework, right? So we're providing an ergonomic api for you to develop components, and by composing your components together, you can develop a web user interface. From there on, we have an angular tooling team that is responsible for building the angular command line interface. The angular CLI allows you to very quickly scaffold angular applications and also production build that can optimize the assets to the maximum so that your users are getting the smallest javascript bundles possible, as well as their load time experience, initial startup experience is optimized. The angular CLI team also works on the migration experience. So from version to version, we would want to make your migration experience as smooth as possible. In general, we're aiming for this evergreen angular. Or just by running ng-update, you can get the latest version of angular, and you can even integrate this as part of your CI process, getting automated updates, pull requests, why not? There were some folks from KOM doing it. On the other side, we also have the angular components team. The components team, they're working on the cdk, which is the Component Development Kit. The cdk is providing a foundation for development of UI components. For example, by using this foundation, you can style the minimum amount of components that we're providing there for your own purposes, as well as use the tooling that we're building for accessible angular applications. The components team is also working on angular UI components based on the material specification. So if you have an angular app that is following it, you can directly take these widgets and put them in your app, and everything is going to work out of the box. On top of that, we also have an internalization pipeline. We have a language service, router, animations, and so on and so forth. In general, we're providing this integrated development stack for web user interface. And I believe that the most unique thing about this is that it is really well battle-tested across 2,000 and even more web applications across Google. These web applications vary from a small, like, internal dashboard, let's say, to large enterprise applications, such as the Google cloud Console. And it has millions of lines of typescript and angular inside of it. We as engineers at the angular team, we're not only responsible for implementing bug fixes and new features, like doing fun things, we're also responsible for making sure that all these 2,000 applications are functioning properly with angular. So if we introduce a change on GitHub that breaks something, we're supposed to go there and fix it. This helps us to make sure that we're aware of all the changes that are happening, and making sure that they're not going to have any unpredictable effect on your applications. This way also, by making large-scale changes, imagine we change a public api, we need to make sure that it works well in Google cloud, which has several millions of lines of code. We need to implement an automated migration, which is just a code transformation that we have implemented in a couple of hundreds of lines of code that takes all this Google source code and migrates it to the latest api change. We can take this source code and make it available externally. And that's what we do as part of the ng-update command that is going to keep your project up to date across different angular versions. Not only is it going to update your configuration, but also your source code. Now since we're all on the same page, I want to talk more about what we have been up to lately. The good news is that angular version 10 RC is out. Depending on when you're watching this video, maybe version 10 is not even out yet. Now you might be considering that this is yet another rewrite of angular. I hope that with the previous explanation I calmed you up and you're aware that we're not rewriting the framework often. That's mostly because it's not necessary and also we'll have to migrate all these 2,000 pages inside, right? So that's a lot of work. Version 10 just means that we have achieved yet another milestone. We're in general releasing new major versions of angular every 6 months. We do that with several different reasons. First, we want to make sure that we have a predictable release schedule and you're all aware of when exactly the next version is going to come. And also you know that this version may introduce some minor backward incompatible changes. Of course, we're primarily going to take care of them when you run ng-update, but imagine we also update the version of the typescript compiler. This means that you may have some typing issues that you should take care of yourself. Of course, these typing issues are just going to make your application stricter and from there, you'll be able to get some hints from the typescript compiler and catch errors ahead of time. But still, this is maybe something that you'd want additional planning around. Now, let me spend some time talking about some of our motivations for moving angular forward. I strongly believe that if you understand the theoretical foundation of all of this, you'll be better aligned with our roadmap for angular in general. I want to talk about predictability versus flexibility. Obviously, we want to have both, right? We want to have a predictable system, which is also very flexible. But this often doesn't work great because predictable systems, they have some constraints. In order for a system to be predictable, it needs to follow some predefined constraints that we know that we can rely on. But at the same time, if we want a system to be flexible, we should ignore some of these constraints. That's why I'm calling this the predictable versus flexible trade-off. Because I'm quite excited about programming languages in general. Usually in computer science, folks are referring to this trade-off as static versus dynamic. Probably you have heard about static typing versus dynamic typing, or strong typing versus weak typing. In this particular case, like strong versus static, these are orthogonal concepts. So let us think about static and dynamic for a second. If we try to place different programming languages that are popular right now onto this axis, we're going to see something like this. Idris is a very powerful language that has a really restrictive type system. We have Haskell with a very restrictive type system as well, and rust as well. rust has a lot of compile-time guarantees about memory management. At the same time, though, it could be really hard to rapidly ship a rust program because you have a compiler that is setting some restrictions on top of you. In order to push you to have a predictable system, it needs to set some constraints. On the other side of the spectrum, we have very dynamic languages such as javascript and Ruby. They are great for rapid prototyping, but at the same time, we don't have a compiler that can look after us and make sure that we're not doing any silly mistakes. typescript is somewhere in the middle. typescript is great in general. typescript helps us to find the best from both worlds, and we can balance by using different type scripts' strictness flags. For example, if you have strict no checks, we're going to go slightly more on the static side compared to the dynamic. Another important observation about static versus dynamic is that it's very easy to go from static to dynamic. This means that you should just relax some of the constraints, and your system is going to go from predictable to more flexible one. However, it's really tough to go from a very dynamic system to a very static system without breaking existing infrastructure. If we put this into more practical terms, we can think of the static systems as systems which are really well optimizable at compile time. The compiler can reason about your program much better if it has some metadata about your type annotations. It can just take your program and transform it to a more efficient version of itself. Also, text editors and IDs can take advantage of this feature as well. They can just look at your source code by using their language service and give you really great auto-completion suggestions, and also even show you inline different type checking errors that you have. Source code visualization is a very exciting feature. One of my first ng-conf, I presented a talk called the Mad Science with the angular compiler. There I implemented a compiler which takes your angular application and compiles it to a virtual reality. You are able to walk inside of this virtual reality with, let's say, Google Cardboard, and you are able to look around and explore your application in the 3d world, having your components being trees, with crowns being their templates, and so on and so forth. I know that this is a very silly example and not very practical in the real world scenario, but it shows that a static system can help you achieve this. It allows you to perform very in-depth static analysis of your application and do some crazy things. This applied in a real world scenario for a really useful application could be a system for reverse engineering of an application. You can build a source code visualizer which just shows individual modules in your system, the individual components and their relationship between one another. This is a really important concept, especially when you're onboarding new developers, because visually it's more convenient for us as humans to reason about systems. On the other side, of course, if you have a static system, this means that you need to have usually a compiler that enforces some guarantees, and this compilation takes time. You have a build process, which can, depending on your type system, can take from a couple of minutes to even hours if you have a large project. On the other side, with dynamic systems, you don't have a build process, because you don't have anything to be enforced at build time. However, you also have some benefits. You can very easily lazy load components, you can dynamically assemble UI, and so on and so forth. This statement is not something novel that I came up with. In general, there are many people, like hundreds of thousands probably, who have come up with the same conclusion. Of course, it's great if we create programs that work out of the box from the beginning. It's perfect. We all want that. We want to create bug-free programs and ship them to our users immediately. But in the real world, things don't usually go this way. We're developers, we're humans, we deal with very complicated systems, so we make mistakes once in a while. The second best thing that can happen to you after the one for shipping a system without any bugs and working from the first time is to catch those bugs very early in the process, before you ship your source code to production. If your compiler tells you about some of the bugs that exist in your program, that's going to be ideal. So there is a survey from quite a few years ago, actually, called To Type or Not to Type. There are researchers from the academia and from Microsoft. They're looking at typescript and Flow and open source projects. When looking at the issue trackers of these open source projects, these researchers are trying to figure out how many of these issues could have been caught by using the typescript type system. This way, you will be able to catch this error during your development process without someone reporting it to you. They figure out that about 15% of these bugs were able to be caught at build time by using type system. See how these predictive systems are quite powerful. We're catching errors ahead of time. And that was many years ago when typescript was still in version 2.0. Now it is in version 3.9 and the typescript type system is so much more powerful with so many more constraints that can help us catch errors ahead of time much easier. All right. So I want to put the static versus dynamic in comparison between AngularJS and angular. If you have been an AngularJS developer in the past, you know that angular was very dynamic. You rarely needed any build process. You just have your framework. You just push some javascript out there. You push this into the browser without compilation, without anything, and you start developing. And you're getting some runtime errors once in a while, right? And that was perfectly ideal for 2009, 2010, when we weren't building applications with millions of lines of javascript. However, now we want to have more guarantees. We were building more complicated systems. And in angular, with this in mind, we started with version 2.0 being very static, with a lot of constraints, with very strict compiler that was slapping your hands if you were doing something against its specification. However, we realized that this made your build process slower, and also we wanted to enable some more dynamic behavior. So what we did in version 4.0 is to relax the restrictions of the compiler a little bit. We did the same with our most recent changes in the angular compiler under Ivy. Now Ivy has more local properties that are performing type checking and compilation in a slightly different way. We're doing less work, so the builds are faster. Now let us peek a little bit into the future. I hope that you have some better understanding of why type systems can help to catch errors, and also to introduce some conventions that allow different tools to glue better together. Now I want to talk a little bit about version 10. In general, the biggest things that we're doing for version 10 are enabling you to have an opt-in strict flag for angular projects, and also a community effort to increase the visibility on how we're making decisions. Let's talk about the second thing more. Over the past many years, we have been forming and shaping our roadmap just by collecting feedback from different sources, such as Stack Overflow, GitHub, different issues there, talking to developers on events like the one today we're going to chat in the forums, I hope soon. Also talking to third-part customers like enterprises, large banks, let's say, talking to internal customers, and so on and so forth. So although we have been doing this and our decisions are entirely driven on the requirements of our users, we don't communicate this well enough. We also don't communicate our roadmap well enough. This is something that we would want to improve. So just follow for news. I hope that we're going to surprise you in a positive way. Now the next thing that I want to talk about, which is something that I'm quite excited about, is actually the opt-in strict flag. So with version 10, you will be able to create new projects with strict configuration. This strict configuration is going to enable a couple of things. Stricter typescript type checking, also strict templates. So we're going to check your templates better, whether they align with certain type system specification. We're also going to enable ES5 support under an opt-in flag. So by default, we will not be shipping ES5 bundles to the end user. If however, you want to support browsers that do not support ES2015 yet, you can opt-in into using ES5 by using differential loading. We are also going to disable common JS support by default. If you want to opt into that, if you have some common JS dependencies that you rely on to, you can do it. However, common JS modules are very dynamic. They do not allow us to perform static optimizations by getting rid of pieces of these libraries that you're no longer using. The final thing is reduced side effects. If we make some assumptions about your source code that it doesn't make any global side effects, like adding global variables, for example, we will be able to tree shake it much more efficiently. We'll be able to get rid of the pieces of different libraries, including your own, that you're no longer using. So talking about strictness, this means that if you opt-in into the strict mode that we hope that we eventually are going to enable by default for everyone, you're going to get more of these. And this may seem scary, but remember, if you have more view time errors, this means that you're catching more production errors before your source code reaches the final users. These examples of making your configuration stricter enables us to do a lot of things. For example, we can have automated updates, much more accurate ones. ngUpdate will be able to consume so much more type information if you have strict typescript flags and will be able to perform these migrations more accurately. We are also able right now, thanks to the static nature of the angular ecosystem, to optimize the internalization pipeline. And finally, we're able to perform much better development experience with tools like angular Universal because of some static characteristics of angular. First let me talk a little bit about the zero overhead internalization pipeline that we have. Now, a lot of folks are asking for very dynamic behavior. Imagine you have a platform where you click a single button and we dynamically swap your language without page reload. This sounds great, but it has quite a few problems. First, for each one of your substrings for your localization, there should be another data binding. It doesn't matter whether you're using angular's change detection or some reconciliation algorithm in another framework. This is going to add some runtime overhead. And second of all, we will not be able to properly tree shake your localization files. If you use only 10% of these strings, we will not be able to efficiently get rid of the rest. That is why in angular we're taking a slightly different approach. What we're doing is to compile your application once by using the angular compiler, and where we have internalization markers, we're adding some extra information that we can use in order to replace it with a specific substring for the specific localization that you're using. This way, we are producing n different builds of your application for the n different languages that you support. And this is with zero runtime overhead, and the most efficient way in terms of startup performance. See, this is only possible because of some static constraints, some static processing, some compilation step. Now finally, I want to share a couple of things about angular Universal, which are again related to the static behavior. With angular Universal, very easily right now you can deploy your application just by using two commands. You can do ng add angular slash fire. This is going to automatically bootstrap the angular fires deployment process, which is only possible again because we have some specific convention on how we are treating different packages and how we are running their schematics in order to achieve certain behavior when you add them to your project. Right after that, when you run ng deploy, we're going to deploy your angular Universal application as a Firebase function and pushing your static assets to a CDN. So in the most possible and most optimal way, we'll be able to deploy your angular Universal application with just two commands, only because we're setting some constraints and conventions on top of how angular CLI works. This is also applicable for the jamstack. For example, in both angular Universal and in Scully, we're able to discover all the different routes in your application statically without running your application. This way we can later pre-render them and make them available through a CDN. Again, this is only possible because of some static assumptions that we have, which are only possible since we're driving currently the angular CLI structure and making assumptions about your application structure as well. So if you're left with two things in this presentation, the first one should be it's not scary to update your application to the latest version of angular. All you need to do is just run ng update angular slash CLI and angular slash core. Please do that. We're guaranteeing that we're going to get better with each next version in terms of both migration steps and also runtime and startup performance. And second of all, I hope that you realize what forces this brings to us. So notice how just by having a well-integrated platform with certain static constraints, we're able to deliver great development experience with two commands, deploy your angular Universal application to the cloud, and also provide assumptions about your projects in order to be able to automatically migrate it with a single command. Well, really thank you a lot for listening to my talk. If you have any feedback, please leave it at slash talk. If you have any questions, I would really love to answer them. I really love talking about compilers and static optimization, so feel free to reach out to me at slash mghf. Thank you. Bye. Thank you for the talk, Minko. That was really interesting. And I think in fact so interesting that we didn't get too many questions. We have a couple of them, and let's walk through those. But this is just a reminder for everyone watching that if you still want to get your questions in, now is your time, and I can still ask them to Minko. So let's start with this one from Albert. Any chance angular will incorporate web components with or without lit html or lit element? Yeah. Good question. So we have been supporting web components for a while now. You can take advantage of web components in your angular application right now if you want to. Additionally, we support building web components by using angular itself. A lot of folks prefer to use the higher level APIs that angular provides in order to declare your inputs, your outputs, to even use dependency injection if you want to. And this way you can wrap your angular component into a web component by using the angular elements package. I hope this answers your question. We have a lot of different initiatives where we're using where different projects are using web components under the hood and they're creating angular wrappers on the other side. So both directions are possible. All right. Well, I hope Albert is very pleased with that answer. Next question is from Ishan. How to update multiple projects with a single command? Yeah. So when you run ng update, this is going to migrate all your libraries and projects from this specific angular CLI workspace to the version that you have specified. I guess this answers your second question as well. But in general, if you have multiple angular workspaces, you should run ng updates multiple times. We're going to migrate automatically your entire application and all the libraries in this workspace to the version that you have specified. So yeah. There was a bit of a follow up build there, but that's great. I think you answered that perfectly. From Janice, next question, will dynamically changing translations be supported in the new way thing? Yeah. So we have a yeah, there are some tradeoffs of both approaches. So far the interprenetarization, the way that we have implemented it, it's optimized for performance and the limitation that you have is dynamically changing translations without refreshing the page. We think that this tradeoff is justified. That's why we're working towards this more static approach because this drops your bundle size and also has zero runtime overhead. So you don't create, we don't have any bindings and your application is going to perform really well. On the other side, we cannot dynamically change translations without refreshing the page. For many customers, many angular users, many developers, this is not a concern because of the performance benefits. Some prefer to have the dynamic change of translations. If this is critical for you, if you think that the users of your applications are going to be very frequently changing between different translations and you want to make this as smooth as possible, I'd recommend you to take advantage of the third party module ngxtranslate right now. Something that our new internalization pipeline would allow is to load individual localizations at runtime. This has been a very important feature for different customers who are using angular, for example, in mobile applications with Cordova or similar hybrid environment. So this is what the new internalization pipeline would allow. Completely different question from Bram. Will variables in ngTemplate outlets be strictly typed? I believe so. Yeah, I believe so. The strictest possible mode that we currently support in templates, I believe it already does have strict typing for these as well, unless I have missed something. All right, I see some people frantically typing in the Q&A room, so I'll ask you a question of my own. What do you think about the future of angular? What do you see in the future of angular? Yeah, thank you for asking this question. In general, we're considering, so in general, I'm thinking of the future of frameworks in general in three different axes, three different directions. performance is one of them, developer ergonomics, and correctness. Regarding performance, web browsers are very closely working with frameworks right now nowadays. For example, the Chrome team is collaborating with us constantly, and I know that they're working with react and checking up with vue often. In terms of performance, there are many different areas, but progressive hydration is going to be one of the leading parts there. Another thing is that we should rethink what legacy capabilities of the web platform we're using that are dragging us back. For example, in angular version 8, we dropped ES5 module support by enabling differential loading. Developer ergonomics is very important as well, developing an integrated platform that allows you to bootstrap your projects, develop it, and deploy it with a single command. This is something that at least on the angular team, this has been a really big focus on us. We want to reduce the threshold from creating a new project to shipping it to production. And correctness, I talked a lot about correctness in my talk. I talked about type checking and why this is actually a good thing. Also, there are different conformance checks to make sure that you're staying on the right path, to make sure that you're not loading resources in the wrong order that are going to slow your application down. This is really important to have a bunch of different minting checks. This is something else that we have been working on, and we're also collaborating with Google Chrome on making sure that we don't regress in these terms. So these are three accesses that I think are important. Interesting. It's something I asked someone before working for Big Corp and then contributing to an open source project. What do you think makes it different for you to get the support of your company to work on open source and on this project? We have quite a few contributors who are working outside of Google. Usually there are different motivations. Sometimes the framework is the external company. I'm calling it external, but in fact Google is a customer of angular, just like any other company. So usually the motivation is to have some more internal insights on what is going on next. Although we're trying to make everything public and available for everyone, and we have much more work to do in this direction to do things right. But although everything is public, by still participating in team meetings and contributing actively to the framework, this just provides you better insights. So this is a big benefit for some corporations. On the other side, you also have a much deeper understanding of how everything works in the framework. So if anyone from your company needs really in-depth angular support, you have the experts on site who will be able to debug everything from starting from the runtime of the framework to the compiler, the CLI, and many other features. I guess these are the three of the biggest, two of the biggest benefits that folks may get. And another, of course, is higher visibility. If you're working on a public highly visible project, your company might be able to attract more talent. Yeah, absolutely. We can do one last question. What are your thoughts on using NX as a monorepo setup for angular apps? Sorry, I didn't hear the beginning. What are your thoughts on using NX as a monorepo setup for angular apps? Yeah, excellent question. So yeah, when you're picking a monorepo, there are different alternatives that you can consider. You can use the angular's default workspace setup, which provides you the very basic, the very foundation. NX goes one step further, and it provides you more incrementality in caching for angular, for javascript in particular. I know many different folks are using angular CLI for react and vue apps as well, thanks to the great work that NX are doing. And if you want to go one step further, and you don't want to limit yourself to using just javascript and typescript in the same monorepo, if you want to, if you have a Java backend, let's say, there you can consider using something like Bazel, which is a very large, very scalable build system that is used across many different corporations. It's used in Uber, it's used in Lyft, in Google, it has been powering our build for the past 12 years. And so you can get really great incremental benefits. You can run tests only when your backend changes, for example, when your api schema changes and so on and so forth. So yeah. Absolutely. Okay. Thank you so much for that answer. And I think that concludes our Q&A session, but people can still join you in one of the discussion rooms that is opening up next, where you'll be co-hosting that discussion room together with Maxim Salnikov, who is actually one of my close colleagues, so that's nice. And I'll make sure to drop by a bit. There's also other discussion rooms, one on Alpine JS with Caleb, and then on typescript with Tejas. And also we have a couple of tickets left over for the workshops on typescript. So you can go to for those. So I'll let you go, Minko, and join the room, the discussion room, and people can go there and ask you more questions there. Awesome. Thanks for the questions, Yrsa. See you later. Thank you. Bye-bye.
36 min
18 Jun, 2021

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Workshops on related topic