Video details

Angular Ivy: Build Speed & Bundle Size | Joel Parks

Angular
02.16.2021
English

Joel Parks

Join GrapeCity & ng-conf for this webinar on all the benefits that come with using the Ivy compiler. Walk away knowing how to get smaller bundle sizes, faster build times, and several other features such as consuming View Engine libraries that the Ivy compiler brings to the table.
Get tickets to ng-conf today at ng-conf.org! Slides from presentation: https://bit.ly/WijmoSlides
ng-conf is a three-day Angular conference focused on delivering the highest quality training in the Angular JavaScript framework. 1500+ developers from across the globe converge on Salt Lake City, UT every year to attend talks and workshops by the Angular team and community experts.
Follow us on twitter https://twitter.com/ngconf Official Website: https://www.ng-conf.org/

Transcript

All right, so today I'm going to be going over angular ivy, what it is, its goals, new features that it brings to the table and how you can make the switch to Ivy and take advantage of all these remarkable new things that the Ivy compiler has to offer. So just a little bit of background information. My name is Joe Parks, I work for GRAP City on the WIDJOJO Component Library team, which, like I said, is a component library focused on data visualization and user input controls, which are available to be used in all the major frameworks for JavaScript view. Angular react. So now Ivy is Angola's newest compiler by the angular team, it was initially released with Angular eight. What was made the default compiler for new angular applications with the angular nine release? HIV is replacing the new engine compiler, which had been Engler's default compiler since its release back in ANGULAR four over the angular team, has made it possible to still use the new engine and angular line. You'll just have to opt into using it over the IP compiler. Do know anything after and your nine, you won't be able to opt back into the new engine. Now, it is a large step for angular, so the complete redesign of how the framework functions internally without changing the way that we as developers have to write our angular applications, the redesign of ANGULAR with IV serves two primary purposes, and that's to reach better build times through more incremental compilation and to reach better bundle sizes through improved tree shaking compatibility. The most important part of all of this is that as developers, we won't have to change the way that we write our applications IBMs to be compatible with existing applications. And using it will be as easy as flicking a switch for most projects. Now, a big part of the push for this reduction of bundle sizes, though, improves loading performances across the board, is to help improve the user experience of users who are accessing the applications that we build through mobile devices such as smartphones and tablets. As time has gone on, mobile device usage in order to access the Internet has increased, with it accounting for fifty three percent of all Internet traffic within the US in twenty nineteen. And that number is only expected to keep climbing. Mobile devices, unfortunately, often suffer from bad or slow Internet connections, making it harder for us to deliver the applications as fast as possible. We have solutions that can help us with this, such as using CDs to serve files or progressive web apps to cash assets. The best opportunity we as developers have is to reduce the bundle sizes that our applications produce. Now, along with these two main features, Ivey's also introduce a host of other improvements, along with the two mentioned above, such as improved build errors, faster testing, better to bigging, improved success and style bindings and improved internationalization. We're taking a look at each of these features and a little more depth throughout the presentation, we'll also take some time to go over any potential changes that developers may need to make, as well as building libraries compatible with both Onion and Ivy compilers and consuming those like libraries with your I.V. applications. First improvement that we're going to take a look at is how it helps us shrink our bundle sizes, just as a quick refresher, bundling in JavaScript is an optimization technique that allows us to merge multiple files together into fewer files, meaning that we can render our pages more quickly for our users. Now, what is tree shaking, tree shaking is a term commonly used in the draft script, context, code elimination. The idea is that all execution floods of a program can be represented as a tree of function calls. So the functions are never that are never called to be eliminated. My other thing that should be noted is that if you are using Congress to bundle your applications, Angular will now throw a warning when building your application using IVI. Reason for this warning is that using common jass modules can result in larger bundle sizes when performing production. This is because Common Jass was designed to be used on server side applications and it was not properly optimized to run on client side applications. If you're still using common jass, it's recommended that you switch to using s modules to bundle your applications. To give you an example of what I mean when important functions functionality from another module, Cumming's allows you to pass a variable into the path well s modules requires it to be a string literal. If you take a look at this screenshot of code here, the first line is an import function for congest modules and the second is an import statement for S modules. In the first one, in the required statement, you can see that we're passing along a path variable into the file path or is in the in the second one. It's just the entire path to the location. We're not passing in any variables there. Cummings can take this dynamic approach because of how dependencies are loaded when Congress needs to load modules, it's done at runtime. The modules are loaded, instantiated and evaluated all at once. This is what allows you to do things like pass variables and file parts, since this is done at runtime. It makes it harder for applications to form tree shaking. Yes, module's, however, do not have the same problem because he has module's are more static, they're more statically analyzable, the loading, instantiating and evaluation that takes place is broken up into three distinct phases that can be done separately instead of being required to perform them together, like with Common Jass, this allows us the ability for more efficient tree shaking. Now, how does Evy El-Ashry shaking part of your engine does not want making use of its modules as to do with how I've updates the DOM versus how the view engine parts. When the new engine first processes the application code, it makes a note of all associations between the e-mail properties and the typescript properties, then it goes about creating bindings or set of instructions for each each HTML typescript property association. Since these bindings are component specific, is easier to optimize them in some generic instructions. The resulting template data is then taken by the angular interpreter and transformed into the Tom. So in the side, you can see that there's a little diagram of the render pipeline for the unjam, so it'll take our template HTML that we write convert that over into a set of template data, which then gets handed off to the angular interpreter, which then converts it over to be used by the DOM. Whenever the bindings are created and your only deals with the bindings for change detection, when ANGULAR is notified of a change, all bindings are reevaluated. This process is called dirty checking. After all, bindings are reevaluated, the binding for which property is changed is then marked and updated. Finally, the template data is interpreted and transformed into the DOM with the latest bindings. Driving instead of generating template data and passing it to an interpreter that decides on which operations to run instead of template instructions is now generated directly. The tablet instructions are where the logic that instantiates components creates dominance and runs change detection that lives. Take a look at this I.V. pipeline render image, you can see that we've taken out the two sections, the template data section in the angular interpretor section, and those have been combined into a single template instruction section which uses the template HTML to create the DOM. The final thing to look at in regards to bundling is how much of a decrease in bundle size we see. The annual team says that for small and large applications, we should be seeing a decrease in bundle size of roughly 20 to 30 percent, and that we should expect to see a slightly lower number for medium sized applications. We've done some internal testing and you can see our numbers here in the two images on this slide. Now, these tests show the bundle sizes using the View engine versus the IV compiler, the first column shows the which one controls that we have included in each project. So you can see in each one we've included a different number of controls, different control combinations, et cetera. The second column is our bundle size output in Kilbride's using the compiler, and the third is the bundle size output from the View engine, with the last column showing the bundle size percentage decrease between the two angular compilers. You can see that from our tests, we're seeing over 30 percent decrease in cases of some of the smaller applications as we get into medium sized application, it hovers around twenty five percent when everything send them. We're seeing about a 30 percent decrease in overall bundle size, which is in line with the numbers, the Angola team we're saying that we should expect to see. The second large change that we'll take a look at is the improvements that the Angler team has made in both application build times as well as improved build errors with the release of. Building your application, each bill would force Angular to recompile everything inside of your module and would do so to check and see what it had been changed in your code. It did this because the generated code of the component could be using the internal details of another component. Now, each component references the directives and components it uses only by the Republic APIs, so if you modify an internal detail of a component or a directive, your application will know which other components the code uses, the code that has been modified and only recompile those components. This can lead to massive benefits in build times for applications with a large number of components and directives. Now, instead of being required to recompile the entire application, you're only recompiling those components that need to be recompile. We're going to take a look at a small example here to see what the changes look like in the compilers. So in the sample, we're going to be going over our component car component that takes an input value called car when the input is created. And the car component gets used inside of another component template, the code looks something like this, and you take a look at that screenshot. And then the app component that it's HTML is how we are calling our our car component. On the right side of the screen, you can see that the code that both the View engine and the IV compilers generated as a result of the input that are component requires. You can see the code here. Now, the IV code is only referencing the car components public name. Contrast this to the code that is generated by the compiler, which can see. Here, the view engine generated code is only referencing the private field of car component, the difference that we're seeing here is because of Evy's principle of locality. The principle of Locality IV means that in order to compile a component in IV, HENGGELER only needs information about the component itself, except for the name and package name of its declared dependencies. Most notably, IVI doesn't need metadata of any to Clarabelle dependencies to compile a component. Now, this may just be a small sample, but this applies for large applications as well as small on all the annual team expects billed times to improve roughly 40 percent. Now, the cool thing about these improvements the Angola team is made to Ivy is that is at or ahead of time, builds are noticeably faster. This means that the angular team has been able to make 80 bills default, build IP applications both in developer mode as well as in production. Because of that, I'd like to touch quickly on at Build's because of the changes that allow for these kinds of builds in development mode and not just production mode have made other improvements to our applications that will be touched on later in the presentation. So I feel it's important to have at least a simple understanding of what builds. Now, at or ahead of time, compilation converts your code from angular to HTML and angular HMO and typescript into efficient JavaScript code during the build phase before the browser downloads and runs your code. Compiling your application during the build process will provide faster rendering in the browser. And some reasons that you want use a lot include faster rendering without the browser downloads of pre compiled version of the application, the browser loads executable codes that can render the application immediately without waiting to compile the app first. There are fewer asynchronous requests. The compiler in Line's external e-mail templates and stylesheets with within the application JavaScript eliminating separate Ajax requests for those source files. Smaller, angular framework download sizes. There's no need to download the angular interpretor if the app is already compiled. The compiler, the interpreter is roughly half the size of ANGULAR itself, so omitting it dramatically reduces the application payload. Detect template errors earlier, that compiler detect the anti builds, detect and report template binding errors during the build step before users can see them. And finally, better security at compiles the templates and components in the JavaScript files long before they're served to the client with no templates to read and no risky client side H. HTML or JavaScript evaluations. There are fewer opportunities for injection attacks. So along with these better build times, I've also introduced better build errors that will show when you're building your application. So as you can see here, we've got two different build errors, both of these, one in I've one in the engine are for when you are calling a component that hasn't been imported into your module. So you can see the first one here, it just says that the new component is not known. And then it's saying that if it is added to the add it to your module, if you look at the second one, it's showing the exact line of code that it's on. And the exact file that you're seeing is. So it clears up a some of the readability here. The bullet points of the error message are the same, they let the developer know that the element that the user is trying to load may be a component, but it's not been included as a part of the module that's being built. So now we're going to take a look at some of the changes that eBay is made to allow us to test our applications faster and more efficiently. When the release of IVI Angular now enables us to use at compilation in all phases, including the testing phase, this allows us to catch errors more quickly since we have fewer differences between the testing environment and the production environment. Along with this, the team is also taking the opportunity to revamp angler's implementation of the test bed class and IVI to help improve some of its efficiency. In Ivy Test Bed doesn't reconfirm excuse me, previously test bed would recompile all components between the running of each test or between each statement, regardless of whether there were any changes to be made to components. For example, through overrides, any test bed doesn't recompile components between tests unless a component has been manually overridden, which allows it to avoid recombination between a majority of developer's tests. Will this change the IV team has seen the framework's core acceptance test speeds improve roughly 40 percent. They stated they expect users to see their own application test speeds to be around 40 to 50 percent faster than they previously were. The angular CDK also introduces a testing subclass with version nine, which can be used to implement something called a component harness for test cases. A component harnesses hide implementation details of a component and exposes API, which can be used to retrieve important attributes such as r.i attributes interact with the component as users would without fearing a component storm and get harnesses of related components such as child components or dialogs with many triggers. But the current component. Component harnesses can be used in unit tests, integration tests and tests, the angular CDK comes with two harness environments out of the box. The first one is the test bed harness environment, which can be used for unit tests and integration tests. The second is the protractor harness environment, which is used for end to end test driven by protractor. The test bed harnessed environment is first and foremost meant to be used with Jasmine and Carmen, the de facto angular unit testing stacks, which should work with other test runners and test frameworks as well. Now, we have a lot of tools at our disposal to debug Web applications using simple logging statements in our code, the browser development tools and web extensions. Plenty of ways for us to tackle the issues of debugging our application. But the angular team has given us a new tool with the release of IVI. A global variable called Engie. This new variable allows us to access corresponding angular components. We can not only see the component properties and functions, we can also modify them in our browsers, console and trigger change detection. To use the energy object, you'll need to have your application running in dev mode with the energy object, you can ask Angular for instances of your components directive's inmore. Manually call methods and update states. Trigger change detection with applied changes when you want to see the results of your change detection. By doing this, you can avoid inserting unnecessary line statements in your code because you can see the component state directly in your browser without any further tools. One of the areas that a lot of developers ran into that they had to see during their annual development was the expression changed after it has been checked? Er, the output was pretty messy, which made it hard to debug the issue and find the root cause, as you can see here on the screen shot. This is one of the errors from the view engine of the expression changed after it had been checked. The updated the error messages a little bit, it looks pretty similar, but they've added some some stuff to it here. So, for example, if you take a look at the app component template in the stack trace here, which was not in the previous Thackeray's, you can click directly on that and it will take you from the stack trace right to the specific line in the generated code where the error is being from. If you'd like, you can also step into any of these framework instructions to walk through how the framework creates and update your components. And the I.V. compiler and runtime provides improvements for handling styles, as well as the ability to use style variables inside of the HTML template itself. In previous versions of ANGULAR, whichever's whichever style binding was evaluated last on the HTML element would be the one that would be the applied style. For example, take a look at the HTML here so you can see that we're setting three different styles. The red color to our element. We're using the style attribute, we're using the style color attribute, and then in the final one, we are using the style where we are passing in another variable to the color property. If my color and other color were both undefined in this case, then the static red would get ignored because it was overwritten by the styles that came later in the in the element. With the IV compiler, you can use a clear and concise order of precedence to determine which style will take effect when your code is compiled with the most specific style will always have the highest precedence. For example, binding the color of the element through the style color property will override a conflicting binding to the style property. Another nice little change that was included is the ability to now use six variables inside of your HTML templates. You can see from this code snippet that we're setting our systems variable inside of the div and then using that variable inside of the paragraph element down below. Like how typescript catches type errors in your code, angular checks, the expressions and bindings within your application templates, you can report any type errors that it finds. The move from the View engine to I.B.. The ANGULAR team has made some improvements to allow for easier error detection with a full template type check setting, as well as adding a new setting. The strict templates. Now, before we get into any new changes for type checking in, I mean, do a quick review of template type checking in ANGULAR eight. So the following component here will display a list of countries for us. And you can see here in the first screenshot, it's our component that typescript file. We have a list of countries here. We also have a title that is currently commented out. Inside of our HMO, you can see that we are trying to call the title and we also are using the incorrect variable name for the country code properties. You can see the C is capitalized instead of lowercase. Now, we're also setting a. We are also setting the full template type check, which you can do inside of the config Jason file. Now, once this is done, we'll run an energy bill and everything will compile successfully and we'll even get some output here, but there will be some issues. So as you can see here, this list is the output of our application, as you can see that it's missing both the country codes as well as the title that we wanted to include above the. Now, will we run into an issue when trying to build this application while using a lot more ahead of time completion by running the energy build broad command, we run this command. You'll see the following error, which you can see on the screen here. When both a hottie and the full template type check properties are set to win with an able and with a full template type check property set to true angular content, we make references to a model that's missing from our component. Now, when the full 10 foot type checked property is set to true and we're using at compilation angler's a lot more aggressive in its type, checking within templates, embedded views such as those within engy for an NGF are checked pipes to check to make sure they have the correct return type. And local references to directives and pipes are check to make sure they have the correct type, except for any generic parameters that they may have. Now we'll take a look at how Ivy handles type checking when building a project while using Ivy will navigate back to its config JSON file and make sure that full template type check is set to true. Now, when we run the application using just energy build, not energy, build pride, we'll see a similar air to the one that we had seen previously with the production build. As you can see here, it's saying the property title does not exist on paper. It's also giving us a little bit more information. It's telling us what file that error is occurring in, which is the app component, that HTML file. And it's also telling us that the title is What's Causing the Error. There's no Title one property inside of the typescript. It does not exist on paper subcomponent. Now, if you remember, I've uses a lot by default, so we're going to be seeing these errors without having to specify a production bill. Because of the change in not being utilized in all forms of the bill, developers will not be able to catch these Templar type checking errors sooner rather than later. If you go back into your app component, that's file, we'll we'll fix that that misspelled code. And we'll also add back our Title one comment that out. And if we rerun it, we'll see the following output, your nine. Or with your sorry, you can see the title countries and your IVI, and that includes both the codes as well as the country names. Now, we'll take a quick look at the new setting added to allow for more type checking in Ivy, which is strict mode with the strict strict template setting, strict mode is a superset of full mode and can be used by setting the strict template setting to true. Now in strict mode, Ivy adds checks that go beyond those in full mode, which is set with the full template mode, including verifying that components and directive bindings are assignable to their inputs. Obeying type scripts, strict, no checks, flags on validating the above infers the correct type of components and directives, including generics in first template context types where configured, for example, allow incorrect type checking for engie for loops. Infers the correct type of event in components and directives domme, an animation event finding bindings and infers the correct type of local references to Domme elements based on the tags name. Now, to enable strict mode. First you need to go back to the config Jason file where we had the full template type checking. You want to replace that with the strip template setting and set that to true. And that will enable the that will enable strict mode when you're building your applications. The I.V. compiler also makes improvements on internationalization and localizing for applications, internationalization is the process of designing and preparing your app to be usable in different languages. Localization is the process of translating your internationalized app into specific languages for particular locales. Target items that you want to add localized messages to, you'll need to include the 18 and a tribute on these elements like you can see here in this little hello world snipper. The angular compiler will replace this text when compiling the template with different text and a set of translations was provided in the compiler configuration, these tags are very powerful. They can be used in attributes as well as content, and they can be included in complex nested ICU expressions as well as have metadata attached to them. However, there are a few issues that arose with the localization in internationalization in the engine, the most significant concern was that translation had to happen during template compilation, which occurs right at the start of the build pipeline. A result of this is that the full build compilation, bundling, modification, etc. had to happen for each locale that you wanted to support in your application. So if a single bill to say, for example, three minutes and the total billed time was or you wanted to support, say, a dozen languages, that would be over 30 minutes to do all of those bills. Moreover, it was not possible to mark text in application code for translation only text in component templates. This resulted in some weird work arounds where developers would create artificial components that exist solely to hold text that would later be used to be translated. And then finally, it was not possible to load translation's at runtime, which meant that it was impossible for applications to be provided to an end user who might want to provide translations of their own. The I.V. compiler has been redesigned to generate a localized tag string rather than doing the translations itself. This means that after the angular compiler has completed its work, all the template text, it's been marked with the eye and attributes have been converted into localized had strings, which then can be processed just like any other tag string. Now, if you're using angular nine or a later version of ANGULAR, your project will have an IV enabled by default. If you're currently working in ANGULAR eight, you're currently using the View engine, which is enabled by default. Unless you've decided to enable the IP compiler, though, it is recommended that you upgrade to a newer version of ANGULAR if you intend to use it. There's a lot you get the most up to date features and fixes that the your team has released for the compiler. If you're upgrading an already existing application to use EBE, the ANGULAR team has done their best to make it so the developers will have to do the minimal amount of work to get their application running with Ivy. But there still may be a few changes that developers will have to make. Now, if you are seeing air travel using IV in ANGULAR eight, the first thing that you want to do is turn off. I mean, this can be done in the RTS config, JSON file underneath the angular compiler option setting. As you can see here, this is how you would enable IV in an angular eight application. If you want to disable IVI, you'll just set enable IV to false. Now, like I said, if you're seeing errors while you're using IV, the first thing you want to do is turn it off, then you want to try running it again. If you're still seeing errors, then you know that this is an IV related. If your application runs perfectly fine, then you'll know that you're probably running into some IP related issues. Now, some of these more common issues you may see include the following, so by default at Ponton Children, queries will only search direct child moods in the dorm hierarchy. Previously, they would search any nesting level in the dorm as long as another directive wasn't matched above it. All classes that use angular design must have an angular decorator like at DirecTV or at injectable. Previously, undecorated classes were allowed in at mode only if only if injection flags were used. Unbound inputs for directives are now set upon creation of the view before change detection runs and static attributes set directly in the achievement of a template will override any conflicting host attributes set by directives or components. Now, there's also a handful of less common changes, as you can see here, that developers may need to make, these ones are a lot rarer than the initial four that I had outlined. So we won't go over these in detail, but I will make the the slideshow available afterwards after that is complete so that if you would like to take a look at all of these and. Now we'll go over building and consuming libraries with Ivy. So the change from the engine compiler to the IP compiler developers may wonder if they need to continue, if they will continue to be able to use libraries built in the unjam. Thankfully, the angular team has created the IV Compatability Compiler or NBCC, to allow us to use libraries built in The View engine with the IP compiler. Now, the compatability compiler passes the pre compile JavaScript code that gets produced by The View engine compiler, it then goes through and updates this code as though it had been compiled by the IP compiler. So if you're using libraries built in The View engine, but you're using IV, you will need to use the compatability compiler to do so inside of your projects package. That JSON file, you'll want to add a post install and script. As you can see here, the posts and Solanke, the script will run on every installation of node modules, including those performed by Engy Update as well as Energy and. Now, the compatability compiler works by scanning the node modules forger folder for packages that are in angular package format or APV by checking the metadata JSON files, the compatability compiler will then produce Ivy compatible versions for each of these packages. So if you are a library author or you are supporting any angular libraries that people are using, the angular team still recommends building your libraries with the View engine compiler over the IP compiler. The reason for this is that I've generated code isn't backwards compatible with the view engine stops that are using your view engine won't be able to make use of them. So if you really say an update that's built only in IV. If you have any any users who are on build engine, they won't be able to make use of that newest build. Furthermore, the IV instructions are not yet. The internal instructions are not yet stable, which can potentially break applications that are using different versions of ANGULAR than the one used to build the library. So this means that if, say, you've built a your your library on a different version of IVI than what your users are using, that may cause issues with your library. So what the IV team recommends is to just let the angular CLIA use the compatibility compiler to convert your view engine generated code into IVI compatible. Currently, there's no need to rewrite your your libraries inside of you and your IP. And that is comes to the end of the the webinar that covers all of the major changes that the England team has been able to make with switching over from the View engine compiler to the IP compiler. I know that we've kind of covered a lot in this presentation, so I'd just like to do a quick rehash of the two biggest changes and reasons for switching over to the IB compiler, the first one being improved, bundling Ivey's change, how it handles rendering versus how the engine handles in The View engine created template data from template HTML, which then use the your interpreter to translate that over the Dom Ivey has gotten rid of the interpreter in that template data. Now we just use template instructions to convert our template HTML over into our DOM. And the second is the improved build times. Now that the angular team's making use of the principle of locality one building applications, we are seeing improved build times. The principle of locality means that in order to compile a component in IVI, Angular only needs information about that component itself. That component itself, except for the name and package name of the Clarabelle dependencies, i.e. doesn't need any of the metadata of the Clarabelle dependencies to file a component which is made at compilation much faster and the default completion method for both dev and production. So as we've seen, there are some small changes that developers will need to make in that process of upgrading from The View engine compiler to IVI, but outside of any potential changes, the change under I.B. is done in a way that we as developers won't need to change the based way that we write our applications, which gives us all the benefits of the changes that the team has made on the backend. All right, that's it for the my presentation here. Yes, we can go over questions now. Yeah.