How to stay fast and fresh with Angular

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC PLAYING] STEPHEN FLUIN: Hello, and welcome. My name is Stephen Fluin. I'm a developer advocate on the Angular team here at Google. My job is really fun, because I get to help developers be successful with Angular. And I get to spend a lot of time listening and engaging with the community so we can reflect your needs on to the team. One of the things that we've learned, having worked with a lot of developers across the world, is that staying up to date is really, really important. And so today's talk is all about how to keep your application as fast as possible and as fresh as possible using Angular. We're going to be diving into some of the best practices that you should be following as an application developer. And we'll take a look at live code and see how you could actually go in and debug and build your application out. So let's actually get started. So if we take a look at what we've got here, this is a application that I've built using the Angular CLI. So it's a very, very basic application. This should look very, very familiar. It's basically we ran ng new, and then we installed something called Angular Material. And so if you take a look at the app component, I've put in an app dashboard. And so if we ran a command like ng serve, what we would see is a normal dashboard of an application that's coming from Angular Material. So we've got a few dependencies installed. We've got a few other things installed. And all of that should just be coming to you automatically. So here we go. This is just the default blank dashboard. And so even though we haven't written a ton of code, we've got an application up and running. And it's pulling in a ton of code, right? We're pulling in the features of Angular necessary for these animations, for these menus, for these dialogs, as well as for all of this content around this dashboard that a user could interact with and engage with. And so the first thing I want to do in order to make my application fast as possible is I really want to understand my application, so we're going to make a couple of changes within our build configuration in the angular.json file. So what we're going to do is we're going to find the angular.json file. You're going to find this directly in the root of your application. And what we're going to do is we're going to find in the production build settings we're going to change two settings here. We're going to say source map-- I'm going to change that from false to true. As well as in our names chunks, we're going to turn that one to true. What source map does is this will actually take my application and map all of the generated JavaScript that comes out of the build and map it back into the code that that JavaScript came from. And so if some of the generated code came from your interior, we'll see that. If it came from Angular itself, we'll see that. And we'll even see things like the generated JavaScript being mapped back to my HTML and into the application code that I'm writing for all the components that I'm creating. And so source maps are a really great way for you to understand what's going on in your application and the relationship between what happens in the code you write in the IDE and the codes being delivered to your users. And so there's a lot of steps that we end up taking along that way, right? There's the Angular compiler that takes that HTML and turns it into JavaScript. But there's also other steps that we do, like optimizations where we'll change some of the property names. You've got bundling, so that we get all of this JavaScript coming down as a single cohesive bundle that makes sense to browsers. And so source map allows us to follow that path, follow that process, and give us really good insights. And so what we can do is, having made these two changes, we can actually now go and run an ng build --prod. And what that will do is that will create a production build of our application, which is normally what you should have done to browsers. But because we've turned on source maps and we've turned on name chunks, we'll actually see the JavaScript and be able to analyze those chunks. And so we're also going to be using another tool today, called Source Map Explorer. There's a bunch of other tools out there that developers use to analyze bundle size and chunk size. But what we, on the Angular team, actually really strongly recommend is you only use Source Map Explorer, because there are tools out there, like webpack-bundle-analyzer, that categorically misrecognize some of those steps within our process. And so we've done that production build. And now whenever you want to actually take a look at what a source map looks like, we can just run Source Map Explorer. If you don't have this installed, you can just install it globally-- yarn global add source-map-explorer. Or you can install it local to your project. Whichever makes sense to you, just go ahead and do that. And what we'll do is we'll run Source Map Explorer, and we will pass it in the JavaScript file that we want to analyze. And so we can see that we've got our dist folder here. And we're going to look at the es2015 version of our JavaScript. So if we run that, it's going to pop up in a web browser. And we're going to see this visual interactive story about our application. So we can see our overall bundle size in terms of minified, but not compressed JavaScript. So it's actually a little bit smaller when it goes over the network. We have about 452 kilobytes of application. And what's really, really helpful here is that you can see where that bundle size is coming from. So you can see animations is 64 kilobytes. Angular Material is about 56 kilobytes. We've got things like HTTP where we might actually need these things. And we might not even know in our bundle. We might have forgotten it's somewhere along the way. So you can see I'm pulling in forms and HTTP. If we actually go into our application, now that we know that those things are there, we can say, hey, I don't actually need that for this dashboard, right? If we look at the content I'm showing here, there's no form data here. There's no data coming from the internet. And I can go into my app module, and I could pull those out. And so I'll just comment these out, because we don't need HTTP or forms. And what should happen is, when I do my next production bundle, all of that code's going to be left out. And so we're going to be able to see that our bundle size will come down from around 450kb to a little bit less than that, which is really, really nice. And it should actually be exactly leaving out the size of the HTTP bundle and the size of the forms bundle. And so source maps are one of the best tools in your toolbox. And we really recommend that every developer be using source maps for using this on a regular basis to understand your application, especially when you're doing any sort of performance optimization. Now, let's say that you are looking at your bundle, and you're saying it's still too big, but I need all of those features. I need all of those capabilities. Fortunately, the Angular CLI offers a lot of really smart capabilities. One of those capabilities is being able to take an application and build out lazy loaded modules. And so let's actually go ahead and do this. And so I'm going to use the CLI here, and I'm going to say, ng, which is the Angular command. And I'm going to say, generate module. And I'm going to give it a root module that it's going to connect back to. So what we're going to do is we're going to create a separate part of our application where we can pull in features that we need and just leave all of that code outside of the main bundle. And so we're going to generate a module here, and I'll just link it back to the module known as app module, which is the root of my application. And now, I'm going to give it a route. And so what this does is it automatically wires up this module to be lazy loaded whenever a user hits that route. And so we'll just make, for example, an about page. And so what this is going to do, it's going to generate a module called about module. It's going to be able to route to it. And then it's going to give me an about component. So we can see all of that in our source code. So let's just close all these files, and we're going to see it created a new about folder with our new module and our new code. And so if we do another production build, what we'll actually see, because we turned on named chunks, we'll actually get out now not only a main chunk, a main module, we're also going to get out an about module. And we can see and independently verify the size of that module and independently verify what the dependencies of that module are doing to the overall bundle size of our application. And so what you'll see is that, by default, an Angular module is really, really small. It's very, very thin. It doesn't add a ton of bundle size to your application. It's almost always the dependencies that you are pulling in, as a developer, the features that you are reaching out for. And what Angular will do is intelligently, based on where you do the imports, will lazy load and split that code. So if you remember, we pulled HTTP and forms out of our main chunk. We can actually now pull that in. And so you can see that we've generated a-- let's just clear this out. And let's take a look at our dist folder here. You can see we've got a main chunk, and now we've got this nice new about module. And as you can see in the es2015 version, our about module's only about 1.1K of code. So it's just that about component, because it doesn't have any dependencies. But if we add back in more dependencies into that chunk-- if we wanted to pull in, for example, Angular Material into that about module-- then it's going to pull in that code. But it's going to do it very, very intelligently. It's going to lazy load all of that code. And so if you haven't set up lazy loading before, it's really, really easy. Just generate a new module with that command that I showed where we generate a module, and we hang it onto the routing structure of our application. All right. Next up, I want to talk a little bit about what happens after we build an application. After we've been building it out and we've added more and more features, it's very, very easy to backslide. One of the things that the Chrome team has seen consistently is that even applications we've spent a ton of time building great performance into their apps tend to backslide. Because we, as developers, we want to add more features. We want to push more functional into our users. And that often comes with more dependencies, which sometimes we don't realize is negatively affecting our bundle size. And so one of the features that's built into the Angular CLI is called Bundle Budgets. And so, again, if we go back into our Angular JSON-- and so we'll just search for that-- we can see this nice little budgets section. And what this does is it allows you to set several different budgets for your application. And by default, we give you two out of the box. We give you an initial budget. So this is the JavaScript that it takes to load the initial page of your application. So right now, we are warning at two megabytes. So we'll see a warning as part of our build if our application is over two megabytes. And our build will actually error out if it's more than five megabytes. And so those are very, very conservative defaults. We recommend you turn those as small as you can, to really just give yourself a knowledge of when you're increasing your bundle size so that it's a conscious choice, rather than an accident. You'll see we also have a few other types of budgets, including any component style. So what it says is that any scoped styles to a component, we want to keep those under 6 kilobytes. And we are going to error out if they become above 10 kilobytes. And there's a few more that you can see, if you just take a look in your IDE. You've got allScript. So that's just, what is the total sum of all the scripts my application? Any scripts or any individual scripts shouldn't be bigger than this, the whole bundle overall, all those sorts of things. So we've got a whole bunch of different features that allow you to really take control and understand and prevent bundle size increases. So that's a really, really helpful tool. So those are some of the top things that you should be doing to keep your application as fast as possible. But one of the best things you can do that doesn't take a lot of work is actually staying up to date with Angular. So if we jump back to the terminal here, what we'll see is that I actually created this Angular application on an old version of Angular. It is running Version 8. So Version 8 is not the latest version. Version 9, as of this filming, is the latest version. And Version 10 is coming out, but it's always the same. So if you're on an out-of-date version of Angular, your bundle size is going to be bigger and slower than it needs to be. Because what happens is, over time, every time we do a release, the Angular team is looking at what can we do better. With the release of Version 8, we actually made a huge step forward by automatically doing something called differential loading, where, because we have this opinionated control of the entire tool chain, we understand how to make your production bundles. And so what we did is we said, hey, modern browsers are capable of loading JavaScript differently than legacy browsers that don't support something called es modules. And so using that knowledge, you can actually conditionally force modern browsers to load modern JavaScript and legacy browsers to load legacy JavaScript. And this is a really nice schism that allows you to have two bundles that really gives you the best of both worlds where you can ship the smallest, fastest JavaScript to modern browsers that support the most recent capabilities, like classes, like modules, all those sorts of things. And you can leave an older legacy bundle for browsers that don't have that kind of support. And so we actually did this out of the box, by default. So you noticed when we were doing those builds, we were actually getting the two JavaScript bundles for each of the files. So we had an about module 2015, and we had an about module es5. And so again, this is one of the changes that the Angular team did behind the scenes, without having to make you change any of the code in your application. And this is something that we do every single release. And so what we're going to do now is we're going to make our application as fresh as possible. So we're going to update to the latest version of Angular, and we're going to automatically get more improvements to our bundle size. This is something that just happens every time you keep your application up to date using Angular. And so we're going to, again, use the ng cli command. And we're going to use ng update. And we're going to update our application in a couple of stages. First, we're going to update the Angular core packages-- so core and the core package-- as well as the CLI package. And then what we're going to do is we're going to go and update our dependencies. So we're going to do it as two steps, to make sure that we don't accidentally enter a mistake or an error where our application is no longer compatible with one of those dependencies. So let's go ahead and get this started. So I'm going to run ng update. And what we're going to do is we're going to pass it angular/cli and angular/core. Now, if you were on an even older version, what we do is we recommend that you go one version at a time, just that we can apply things cleanly. And if you want to do that-- for example, if you were on Version 6 and you wanted to go to Version 7-- you can just say @7, and that will just do that for you. But we're going to go all the way from Version 8 up to Version 9, which is the latest. So I'm going to run this command. And theoretically, things should work. There's a few places where this might fail. If your repository isn't clean, then what should happen is we're going to throw this warning, which is what we're seeing right now. Repository is not clean. Please commit. Because what we want is we want you to have a very clean history so that you actually know what the Angular update process did. Because this isn't like a normal ng update where we're just modifying the node modules of your project. We're actually making changes to your application so that you stay compatible with Angular. And the reason we're able to do this is because the Angular team at Google, we have thousands of projects across Google that are not run by our team that are using Angular. And it's actually, according to Google policy, our responsibility for keeping those applications working as we make breaking changes to Angular. And so the only way that we could scale this at Google is to build really great automation and really great tooling. And so what we did is we baked that same sort of tooling into the public world into this ng update command. And so whenever we need to change a method name, whenever we need to deprecate something, we're going to try and update your application as best we can. And so that's why we always make sure that you want to have a clean history, so we'll just git add everything. We'll commit that. And then we should be able to run our update command. So again, what's happening behind the scenes is it's going to be downloading and installing the latest version of Angular CLI. And then it's going to be updating the packages on my application and changing my code where needed. And so if there's any sort of migrations, what should happen is, while you're doing the update process, it's going to report what migrations it's doing. So you can see Angular workspace migration. So it made a few changes to the workspace layout. So you can see it updated my angular.json file, updated my tsconfig.app. It updated the packages. And so it's making all of these migrations. Even ones that don't really have any changes to my app, it's still double-checking all those things so that we know that my application's going to keep working. Now, there's a couple of other places that you can look for the latest information. You'll notice here at the very, very bottom of the update, it actually says, for more information, please see this link. And so we actually have guides on what changes we're making behind the scenes with every version of Angular, so that you can know about things like deprecations, you can know about things like removals and changes to the way that the APIs work. The other one that I want to point you out to would be update.angular.io. So behind the scenes when you ran ng update, we made a lot of changes to your project. And so if you actually wanted to see what you need to do, you can just go to the update guide, and you can say, show me how to update. And we'll say, oh, make sure you're on the latest version here. Make sure you're using this version of Node. It walks you through the changes that are going to affect you, as a developer. And you can even tune this, based on the number and amount of features and the depth and complexity of your usage of Angular. Because most applications don't care about all the changes we're making under the hood. But let's say you have a large application. Maybe you have several hundred components. You have component libraries. You're using things like Universal. You can check these boxes, and what it will do is it will show you all of the information about the update, all of the changes we're making behind the scenes so you can have a full, complete understanding of what's going on. The other way you can do it is if you just take a look at the git history. You can now go in and see what all the changes we made were. So for example, when we moved to Version 9, we turned on ahead of time compilation by default. So that's going to make your build a lot faster. You can see that we've installed all the dependencies, and not just on Angular. We've also installed things like rxjs to the latest version. We've updated your components so that they actually continue working as we make changes to Angular. And so this is really, really powerful. And then we can actually do a test to see if this works. So let's just run an ng serve. And we can say, yes, let's let Google Analytics track some of our CLI usage anonymously. And what will happen is, when we return back to the browser window, we're going to get the latest version of Angular. And our app is generally just going to keep working. And then the way that this really affects you is not only keeping you up to date as a developer, making sure you're using best practices, but again, it's also going to improve the performance of your application. One of the things that you're going to see is that every time we make an update to Angular, we're trying to look for ways to make Angular more tree shakable, to make your build system better. And so there's lots of experimentation, lots of ideation going on there, because the state of bundlers in JavaScript are not static. Webpac keeps getting better. Rollup keeps getting better. Terser keeps getting better. And these tools are changing, and they're evolving, and the way that they relate to each other is changing. And so what we do is, as the Angular team, we're trying to stay on top of that for you. And so let's go ahead and refresh. And if we take a look in the dev tools, we should see we are now on the latest version of Angular-- so 9.1.9 at the writing. But whenever you use ng update, it's just going to move you to the latest version. It's going to do that automatically for you, so that you are staying up to date, staying fresh, staying fast. And so once you've updated Angular and you've updated the CLI by core [INAUDIBLE],, now what I'm going to do is I'm going to go and update all the other packages. So if you take a look, for example, we did not, in our package.json. We didn't update the CDK, or we didn't update Angular Material. And so we're going to do one more ng update command to update Angular Material and Angular CDK. You can do this with any of your dependencies. A lot of dependencies are starting to support these automatic migrations. This is what we've been pushing very hard for in the ecosystem. All right, let's just run that ng update @angular/material and @angular/cdk command again. And again, it's fetching the latest version of those packages. It's updating their dependencies in your package.json. And then it's going to execute any migrations that you need to be on the latest version. And I think we're going to try an ng serve one last time, and we see that our entire application kept on working. And our bundle size should have gotten a little bit better. And again, it's doing a little bit of compiling ahead of time. Generally, this is a temporary thing that you're going to see with Ivy and with Version 9, is that we do this extra compilation. That's really to offer the latest version of Angular and the latest features of Angular, while still staying compatible with the rest of the ecosystem. And so this is just extra compilation stuff the Angular team does to optimize things. All right. As soon as this compilation is complete, what we're going to see is we're going to be on the latest version of Angular. And again, we updated the package.json, so just all of the dependencies, including removing things like HammerJS. And our application should just keep working. Yep, there it is. We have a great dashboard, just like we had before, right in the beginning. Everything works. Everything animates. We're now in the latest version of Angular. We're now in the latest version of Material in the CDK. And our application is as fast as we can be, because we're budgeting. We're making sure that we're understanding our application, making sure it doesn't grow over time. We're analyzing the application bundle size with source maps. And we're doing things like lazy loading, so that we only make users pay for the features that they're using at the current time. That's going to be it for us. Thank you so much for watching, and have a wonderful day. [MUSIC PLAYING]
Info
Channel: Google Chrome Developers
Views: 55,619
Rating: undefined out of 5
Keywords: type: Conference Talk (Full production);, purpose: Educate
Id: B-lipaiZII8
Channel Id: undefined
Length: 20min 15sec (1215 seconds)
Published: Thu Jul 16 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.