Check out a free preview of the full Angular 13 Fundamentals course:
The "Lazy Modules" Lesson is part of the full, Angular 13 Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Lukas discusses strategies for optimizing an application, including breaking it into smaller modules to be lazy-loaded when a user requests the needed module. If a module has dependencies, they must also be included in the standalone module to ensure loading is not dependant on the parent module.

Get Unlimited Access Now

Transcript from the "Lazy Modules" Lesson

>> A common technique for optimizing a heavy application is to break it up into smaller modules or pieces that get loaded lazily or when the user requests. So, imagine you have an application that has let's say 20 features. And your entire payload is massive that I've seen applications sometimes being 20 megabytes large, very large.

[00:00:31] And unfortunately the first time you go to an application like this, you have to download the entire payload to make that work. And so somebody is waiting a very long time for the application to just even do its first meaningful content paint in for to render. And so the idea is, what if we only loaded the pieces that we needed when we needed them?

[00:01:01] And so, a strategy for this or how you approach this is going to depend on your circumstances and more importantly on your users behavior. So for instance, if you have an application that has five features, and your users spend 90% of their time in two of those features, I would recommend loading those in the initial bundle.

[00:01:31] But if the other 10% of their time is spent randomly accessing the other three features, then you could, one break those three up into a second module or into individual modules. So then you have your initial module and maybe three other smaller modules. And so this really is going to depend on how your users use your application and where kind of the behavior is distributed across your entire feature.

[00:02:05] So you could split it up in half, you could do a lazy module for each. The one thing that I do wanna point out that most people will say, like well the more modules the better, that just makes sense, right? Well, especially in countries that have an underdeveloped infrastructure, like third world countries or even drought in like a rural area.

[00:02:33] And you are on a like a 3G network or something equivalent. The most expensive operation you can do on that device is to make an XHR callback to the server. The reason being is that unlike a computer, a phone has to activate hardware pin the tower, do a handshake, then get the thing and then complete it.

[00:03:01] And so, in some cases it is a lot better for the user to have a larger payload but reduce the calls over the wire. So, I just want to put that out there that this is a balance that making XHR calls to a server is also expensive, and if you're on a handheld device, it's very expensive.

[00:03:23] So, depending on your user base, you may want to factor that in. So, with that said, let's talk about how to implement a lazy module. And so, I'm going to go into the code and I'm going to walk through some code that I have preemptively generated and just show you what we are starting with.

[00:03:52] So, when you are lazy loading a module, naturally you need a module, and so this looks exactly like any other module that we would create. So, very similar to our app module, and you'll notice here that we have our component, we also have our lazy routing module. And if we step into this, then what you're gonna see is that we have a route defined for or think of this as a top level component that we have a top level route for this particular module.

[00:04:38] As well as we're doing router module for child because this is going to be added in as a child module and we're not loading this into the route. And so, this is very similar in structure philosophically to the app module over here and its relationship to the app routing module.

[00:05:02] And so in order for this to work, we are going to create a route for this that's going to be a little different than anything we've seen up to this point. So, we're going to create a path and it's going to be lazy. And then from here, we are going to instead of calling component because there is not a component, we are going to instead call load children.

[00:05:44] And this is going to store a function, and so load children is essentially when we go to this that angle under the hood is going to call load children. And then execute the logic that we put in to this particular function. And so from here, what we're going to do is we're going to import or call the import method and we're going to give it a path to the module that we want to load.

[00:06:18] So in this case, it's examples/lazy-module/lazy-module,module. So, I feel like this is either a vocal warm up, a tongue twister or a funny joke, and at this point I'm trolling everybody. And then from here we are going to, because this is going to return a promise, we are going to resolve this using that then.

[00:06:50] And this is something I don't understand why this, they did it like this. Well, I believe the reason why it is a promise, once I think about it for like two seconds is that this is only ever going to resolve once. And so a promise in this case, I believe would make sense.

[00:07:03] And so from here, this is going to take in a single parameter which is m for module, just as c is for cookie, that's good enough for me. And then we're going to define the module that we want to load, so in this case it's pulling in the module.

[00:07:24] And then because within this module here, this is called LazyModule, then it's going ahead and then essentially bootstrapping that module into the angular runtime. And so, just to recap before we check this out, same path, the difference is that we're giving it a function that when we call this it's gonna say loadChildren.

[00:07:49] And it's going to import the module and from here then it's just going to return the module itself, the angular module that we want to essentially instantiate or initialize or bootstrap into the runtime. So now if I go here and I go to lazy module, you'll see here that this is a lazy module.

[00:08:16] Now, one thing I do wanna do is let me go ahead and I'm gonna just clear my cache, Clear data. If we come back here, and we go to the Network tab, I'm going to refresh. And, you'll notice here that this, one of the things that was loaded after it loaded everything else, is this particular module.

[00:08:47] And, so I think I can zoom this up just a bit without loosing it, is that this is pulling this over the wire. So, it's wrapping up this module, the lazy module, into a kind of a standalone separate module. And then when we request it, then it's pulling in the entire module over the wire and then loading it into the application.

[00:09:17] And so this is where if we built another one or we had a number of lazy modules. Every time you navigated to that lazy module, what you would see would be the bundle for that module coming over the wire. And so, executing lazy modules or implementing them is fairly straightforward, you simply treat the piece that you want to isolate.

[00:09:43] So, a lot of times this might be a standalone feature set or even a bit of functionality that is or a couple pieces of functionality. But these go into a module and in a way you have to treat that like almost like a separate application. So a lot of times you'll have separate routes for it, for routing table.

[00:10:06] As well as one thing that you can run into problems is that within the module, if you have dependencies, you need to add those dependencies to that standalone module as well. So that when it's bundled that it has the dependencies that it needs and it's not dependent on the parent module.

[00:10:30] So in this case, because I was using material within our lazy module, I needed to import that as well. And so this is how lazy modules work within an angular application.