Step by Step Improving Startup Performance with Lazy Loading in Angular - Manfred Steyer

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Thank You Maxime so hello everybody and welcome to this dock this talk is about improving startup performance with lazy loading but first of all let me introduce myself I am month red I'm a trained and consultant with focus on of course angular and I'm also part of the Google developer expert program which I'm very proud of I'm from Austria and I'm doing a lot of assignments in Germany and from time to time I'm writing my book is the book with the most ugly cover animal it has been published with órale in germany but anyway a key or not I'm very proud of it of course so what are the contents of this talk first of all I will talk about lazy loading I will show how to leverage lazy loading to improve the performance of your application and I will also talk about pre loading which compensates some issues that comes with pre loading with lazy loading in addition to that I will talk about an issue that arises when you are using lazy loading together with shared models and in addition to that I will also present two solutions for this issue but first things first let's start with lazy loading by the way a good friend of mine told me that I am very authentic when I'm talking about lazy things I'm not sure what he meant but I think it was some kind of compliment perhaps anyway what we are seeing here is that typically structure the typically model structure of an angular application we have this root model called earth model we have some future models and we have one or several shared models and normally angular is loading all those models at once all those models are normally loaded at once when the application starts and this is exactly where lazy loading comes into play because when you are going with lazy loading you can start with the first model of your application and then you can load further models on demand for instance on demand when the user clicks here or there you are loading the first feature model with two shared models it depends on then they use a click somewhere else you are loading a second feature model with another shared model it depends on and of course so you can load all the models you need for your application just on demand so what does it needs to get started with lazy loading all it needs is to use a special route a special routing configuration with this load children property lost children is pointing to the file in question to the file that contains your module you want to lazy reload it also contains this hash sign here as a separation character and then you have to append the name of your module class and this is more or less all you need to do when you want to load a module by the means of lazy loading of course now the question arises which route is activated when this very lazy loaded model gets activated and the answer can be found within the route of this model this model of course has its own route and there we can find perhaps and default route route with an empty bus and this is the route that gets activated when you are triggering lazy loading for a model in addition to that you need a special build configuration you need a build configuration that is just splitting your chunk into several chunks splitting your bundle into several bundles that can be lazy loaded of course when everything would end up in one and the same bundle lazy loading wouldn't make any sense and the good message here is that when you are using this CLI you are done your don't need to do anything else just use this you lie the CLI comes pre-configured with the so called ng tools loader and this loader is just taking care about splitting up your bundle into several chunks that can be lazy loaded so when you are directly going with that back because you need all the flexibility of that back then you can also use ng tools back the fill item is exposing this loader directly for the usage with that back so you don't need to use to seal high to get it and at this point your big thanks to the seal I team for exposing this part of the CLI to the rest of the world there is also alternative to it there is the angular router loader it has been around for quite a time and you can also use this angular route the loader with your own backpack configuration to make sure that your bundle is split up and once again big thanks to Brent Roberts at this time within the presentation cause Brent nice doing so much stuff for the community and sprintin has contributed this loader in very early days in very early days and so he helped us to get started with all those features when these features have been quite young so in general always there are two sides of the coin and this is also true when it comes to lazy loading lazy loading just means that we are loading some parts of the application later we are just postponing work and as you might know postponing work doesn't mean that the work is going away it just means the work has to been done later and this is the truth this is very true here first of all we get a better startup performance because we are postponing the load procedure but then during runtime of course we have to load the model in question and this causes a slight array ah not erase on a delay of course and this is exactly where reloading comes in pre loading helps with this issue the idea behind pre loading is quite easy the idea is that models that might be needed later are directly loaded after the application startup so first the application starts the user sees the first page of the application and then the application is just reloading all the other models so that are available immediately when they are needed so what does it take to get started with pre loading it doesn't take much you just need to register a pre loading strategy and you are doing this when you are setting up the routes for your routes model and this is exactly what I'm doing here on this light here I'm calling route the module for route I'm passing in my route configuration array the array with all the mappings between the Buffs and the components and I'm also passing in this parameter object and as you see here this parameter object is just registering every loading strategy it is using the pre loading strategy preload all models this is a baked in Bree loading strategy pre loading strategy angular offers and as the name suggests it is just reloading all the models that are configured for lazy loading you can also write your own Bree loading strategies very easily it is just a matter of implementing an interface of implementing one and only one methods and this one method decides whether or van a specific module is pre loaded so let's have a look at the demonstration let's find out if this guy here on the stage is saying the truth for this I'm switching to a sample app I've prepared this sample app is about booking flights I'm using the sample app to show many aspects of angular and this sample app has something I have invented I'm calling it log in for very honest people yeah so I've found out that when everyone is honest everything is much more easy in this world so I can log in here and then I can switch to book a flight and here I can search of course for a flight I can also search for a passenger and when I'm locked in then the current users name is proposed here for the best and research so currently the name max is proposed then I'm not logged in then nothing is proposed here so please keep this in mind we will need this a bit later so currently this application is just loading everything mint application stats but now I want to switch to lazy loading and for this I'm switching to my editor here I have the routes of my of my routes model this route mode will have this empty route it has this route for home and here I will just add another route a route that is called flight search above flight search ya and together with flight search I'm using this property that is called load children and load children as mentioned has to point to the model in question I have to point to the model file the name of it is flight booking / flight booking module and then I have to advance the name of the class and the name of the class is also flight booking model so let me just take a bit of water okay fine so this is my route that is triggering lazy loading let's also have a look to the route configuration for this lazy loaded model let's have a look into the flight booking routes within this flight booking routes I have a main route and this route is called flight booking but we have another flight booking route as we have seen before this flight booking route is triggering lazy loading and because of this I am switching here to an empty bus so that this route is directly activated when we are loading our lazy loaded model let's also have a look to our app model here I'm referencing the flight booking model referencing a model that is lazy loaded isn't a good idea because when a bundling solution like that bag is detecting this reference this solution will follow the reference and the solution will take everything that can be found under this reference and put it into the main bundle and as mentioned before when everything ends up in the main bundle lazy loading is impossible so we have to make sure to omit every reference to lazy loaded models II so when I've done everything correctly I should end up with another bundle and here it is my CLI has created a bundle with the name v chunk chairs so the CLI and that back in general is just giving numbers to my bundles and I can configure this to get pretty names for this demonstration I'm just going with numbers so let's switch back to our application let's switch into our network tab and let's reload the application and here we are seeing that everything is loaded everything but the five chunk chess but then I'm switching to book of life when I'm switching to book a flight nothing happens which is quite a pity well come on so let's me save this again I've got my bundle my five chairs let's try it again no nothing happens so the demo gods aren't on my side let's double-check here I have my model here I have my flight booking routes here buddy the import should go away it should be removed by the typescript compiler a comma there is a comma missing okay so somewhere here you think button okay here somewhere no ah no I see yeah twenty-one okay yeah I don't think that this is the issue let's try it again nothing happens after droughts okay ah here thank you you've saved me flight booking of course so when the name is correct everything should work yeah thank you take a blouse to my friend here okay [Applause] thank you and have you seen now my file is loaded now we can see that the file five chest gets loaded on demand so nothing is loaded i switch to book a flight and here we have five Chunk chess awesome isn't it so you have also seen this loading indicator haven't you I'm switching to book a flight loading indicator it takes some seconds to load this additional chunk of which is of course an issue especially when there is low bandwidth and this issue can be prevented by using pre loading for this I'm switching back to my application I'm going down to the point where I'm using the routes where I'm calling router model for route and here I'm passing something like this parameter object a parameter object with reloading strategy and here I'm going as mentioned with preload all models so I'm saving it let's switch back to my application let's clear this reloads and we see that our chunk five chunk chess is loaded but is this loaded quite late so then we look here it is slow that hopefully after the user has seen the first page of the application after the user is about to decide where to click next so it is just triggered after two seconds cool so it seems like reloading and lazy loading works so let's switch to book a flight I'm locking in again I'm switching to book a flight I'm switching to search passenger and as you see we are seeing nothing there is nothing proposed anymore so somehow we've broken our application did we before the current user's name was the chested here and now there is such as the chest at nothing so what did happen here let me explain what happens it is that I seem to have catch a flu and the second thing that happens is that we have these three models here we have the app model we have the flight model and we have a shared model and the shared model has an off service and the off service is remembering the current user's name it is remembering that the user is locked in and that the user has the name Max and the problematic point here is that a lazy loaded model gets its own dependency injection scope and so it gets its own instance of the off service and this is quite a pity because here we are ending up with two instances of a single and as you might know from every good western movie this town isn't big enough for two things and so we have somehow get rid of this second signior and the good message about this is that everything that can't be found within the current dependency injector is looked up one level above and this level above is your take leoben level the level that has this global of service where the user is out indicated so indeed everything we need to accomplish is to get rid of this off service here and it is quite easy to get rid of it there are two patterns you can go with the first pattern is documented somewhere within the angular Doc's it says that you shall use a core model equal model that gets all the global providers global providers like the off service and this core model is only allowed to be imported into the app model by doing this you are guaranteeing that this off service is just a created provided globally globally for the whole application this is the first solution to this but then you are going with the solution you very easily end up with a very very whoo which core model and this is problematic it is also problematic because this pattern is splitting up your composition it is splitting up your shared model into the shared model and into a core model but and that's why I am preferring another solution and the solution is intended for libraries but you can also use it with your own code you find this pattern for instance within the router itself you find this pattern for instance within third party vendor libraries like entry ex translate then you are going with this pattern I would suggest to create a dedicated shared module like an off module you are seeing it here and then and now it is getting a bit awkward this of module has to be provided in two flavors one flavor comes with services and one flavor comes without and I know it sounds a bit awkward that we have to provide our model in two versions but that is the pattern and as mentioned this pattern is widely adopted and angular makes it very easy to implement this pattern the version with the service providers is included into the app model and the other version is included into all other models that needs the declarations of this model some components or pipes for instance and so you are again guaranteeing that the services are just registered within the global dependency injection scope and in nothing other scope so in addition to that you have to write your model and first of all you are writing the model without providers to emphasize this I have just created an empty provider array here and then you are creating a static method this method is normally called for a route I think you know this method from the router and from other tools this method is just returning something Vista type model with providers a model with providers is nothing else than a pre-existing model that is expanded by some service providers and this is exactly what happens here here at this slide you are seeing that I'm going with my existing off model and I'm adding my providers for instance my off service to this off model so after this you are using the four routes version of your model with your routes model normally this is the app model and that in addition to that you are using your off model without for route with all the other models you needed of course you can write some nifty other method for the other models the route of for instance has this four child model you could use your so let's have a look at a demonstration for this let's switch into our application and let's have a look into the shared model the shared model is quite huge and here it is just setting up the provider for the off service I'm taking this out and I'm switching to another file I have prepared the file is called off model so this file is almost empty and here I'm just abandon a model and the model is called half model so I don't have anything to the cure but here I could declare for instance a login component a logout component a user status component whatever and the important thing here is that the providers array is empty it is empty and it stays empty and in addition to this I just create a static four routes method and the aesthetic four root method is returning as mentioned model with providers and this is just an ordinary structure that is pointing to my very own of model and pointing to my providers and here I'm going of course with my off service provider so I'm importing this thing here I'm importing this other thing this other component okay perfect so let's give the CLI some time to rebound perhaps this Eli has finished and before we are switching to our application I am just registering this off model for this I'm switching to the app model and here I'm importing the off model with the services of model dot for routes of course with each other model for instance with the flight booking model we could also import this off model but without calling for routes let's do this for a demonstration purpose I'm switching to flight booking model and Here I am just importing my off model without forward ok so as mentioned let's give the CLI some time to recompile so it is complaining of model is not a model I am not believing this and not believing this let's resave this yeah yeah issues so let's retry this I'm reloading my application I'm logging in I'm Mexican and I'm switching to book a flight and then I want to click on search passenger shall I do it yeah okay let's try it yeah it works wonderful wonderful so it turns out the guy here in the front is saying the truth which is a wonderful thing okay so let me sum up what did we see we have seen that lazy loading can improve your startup performance because you don't need to load everything when the application starts but just your let's say application shell and then you also need a built configuration that is splitting up your whole bundle into several chunks several chunks that can be loaded by the means of lazy loading we have also seen that pre loading helps to prevent this delay during the execution of the application this delay that happens when the model in question is lazy loaded we have also seen that there is this pattern with the core model that bypasses this issue that arises when you are using shared models together with with lazy loading and you have seen this other pattern that is implemented by the router and by some other libraries and this pattern allows you to provide bangshi at module one for perhaps dedicated shared module in two flavors one flavor comes with the services and it is intended for the root model and another flavor comes without services and it is indented for the other models so thanks for coming you will find all I have shown here on my blog Software Architect 80 and I will of course suite a about it so thanks for coming and have a nice conference [Applause] [Music]
Info
Channel: ng-conf
Views: 11,792
Rating: 4.9578948 out of 5
Keywords:
Id: 8VLYjt81-fE
Channel Id: undefined
Length: 29min 48sec (1788 seconds)
Published: Thu Apr 06 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.