One problem with creating a Single Page Application (SPA) is that you might load the entire application when the user first starts the application but most of it is never used. Sure navigation is nice and fast after the initial load but that slows down the initial load as that becomes larger. And that might be worth it if the user navigates to all, or most, routes loaded. But when most routes are never activated that is just a big waste. Fortunately with Angular that is easy enough to fix with lazy loading. And lazy loading is really easy to set up in Angular as well.
BTW This blog post is about Angular 2 but as we are not supposed t0 use the 2 anymore it’s just Angular
Eager loading of routes
Below an example of eager loading with Angular routes. Notice there is no HTTP traffic at all when I click on the different links and different routes are activated. Of course this is a really simple example and in a real application you would most likely be fetching some data using an AJAX call
So what code did I use here?
Most of it was just generated with the Angular CLI. You can see all the code here but it boils down to the main AppModule with two sub modules: Mod1Module and Mod2Module both generated with the CLI and each has a single route and component added to it. The Mod1Module is about books and Mod2Module is about authors. Below is Mod1Module as an example.
The AppModule is also quite straightforward. It adds the two sub modules and initializes the routing module. As both routes used are defined in the sub modules the routing table is actually empty here.
The view for the main AppComponent is also quite simple. There are two links with anchor tags using the RouterLink directive to let the user navigate. Finally there is the RouterOutlet directive to show the route components template.
Running this with ng serve works and as you can see above the application loads everything at startup, no additional requests are done when we click on the route links.
Switching to lazy loading
It turns out that switching to lazy loading is really simple and just requires a few small changes.
We want the sum modules only to be loaded when needed so the main routes need to be defined in AppModule instead. In both Mod1Module and Mod2Module we need to change the route path to an empty string. The only change is on line 8 here.
The majority of the work needs to be done in AppModule. Still it is just a few lines and most of it is deleting code
Note that both the TypeScript as well as the module imports for Mod1Module and Mod2Module are gone. New are the two routes where the books and the authors are defines. Instead of specifying the component to load there is a string ‘./mod1/mod1.module#Mod1Module’ which points to the module file and the module class to load. This is in a string because we don’t want to import the type, they should be in a separate module and only loaded when needed. The documentation here is still a bit sparse as it point to the LoadChildren section which points back to Routes Oh well, the documentation is open source so I guess I should open a pull request
Anyway, with these small changes both Mod1Module and Mod2Module are lazily loaded when first needed and not on the initial page load. Below you can see 0.chunk.js and 1.chunk.js being loaded the first time I click on a link to the respective module.