Lazy-Loading Angular Modules (Ivy and Async Await)
What is Lazy Loading?
If I visited the Admin panel and navigated to Shop, the code related to the Shop would be lazy loaded and “injected” into the browser (in simple terms) for us to use the Shop module.
After compiling and deploying our Angular app, we could have a JS file per lazy loaded module, for example:
The best thing is that when we visit /admin, there is no code downloaded that’s part of our Shop, and vice versa. This keeps bundle sizes small, and code efficiently performant. With this in mind, let’s learn how to lazy load any module with Angular! I also want to show you a newer approach that uses async zawait.
Lazy Loading a Module
Back in TypeScript 2.4 the dynamic import syntax was introduced, this became the defacto way of importing TypeScript modules on the fly (so they weren’t bundled with our code).
Create a Module to Lazy Load
First, we’ll need to create a lazy module in our app, which will use RouterModule.forChild(routes) to define a child module:
Using path: ” allows us to define which route we’ll hit for our LazyModule to be created, we’ll see this momentarily.
At this point, just because our module is “called” lazy, it’s not lazy yet. We’ll need to add this to our root app module, and define the routes we’d like to setup.
Declare the Lazy Load Routes
The way we lazy load Angular modules in v9 and above (with Angular Ivy!) is through the route declarations!
Currently, the Angular documentation suggests a Promise-based syntax for declaring which routes to lazy load, which we add to a loadChildren property on the routes:
But Angular isn’t about Promises, so I find the .then(m => m.LazyModule) a bit of an eyesore, it just feels wrong in the codebase – can we do better?
Using async await
With the addition of async await in TypeScript, we can use the syntactic sugar to clean things up a little!
Changing over our Promise-based routing implementation to using the newer async await syntax looks far nicer.
We can omit the .then() altogether and use the await the return value from await import(…) and reference .LazyModule directly:
Legacy syntax (Angular v7 and below)
Lazy loading in Angular has come a long way since the beginning, where we used magic string to denote a module to be loaded – just for fun here’s what we used to do:
You can see how this could easily be prone to spelling errors and the mystical # to denote the module’s name. Now we just simply reference the object directly which is nicely inferred through TypeScript.
It’s great that Angular Ivy has introduced better techniques for lazy loading that make it even more efficient for us to get setup and code splitting!
If you are serious about your Angular skills, your next step is to take a look at my Angular courses where you’ll learn Angular, TypeScript, RxJS and state management principles from beginning to expert level.
Happy lazy loading!