Preloading Modules — Angular Router

Alex Onozor
alexonozor
Published in
3 min readAug 29, 2017
Preloading modules

Last week was all about lazy-loading, were we learnt how to split our application into feature modules and load them on demand. The issue with lazy-loading is that when the user navigates to the lazy-loadable section of the application, the router will have to fetch the required modules from the server, which will take time.

We can fix this issue by adding preloading to our route, of which the route can load our lazy-loaded modules asynchronously while the user is interacting with other parts of the application, this makes it more faster when the user visit any preloaded module as this will fetch from a cache.

In this article, I will continue from our E-Commerce styled application, adding preloading to the lazy-loaded functionality from where we left it.

In the last article we have a file called main.route.ts where our initial route is setup. which uses the app.module.ts.

Notice: The HomeComponent is eager loaded and angular will render it after the application has finished boostraping .

import { Routes } from '@angular/router';// HomeComponent this components will be eager loaded
import { HomeComponent } from './home/home.component';

export const routes: Routes = [
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'shop', loadChildren: './shop/shop.module#ShopModule' },
{ path: '**', component: HomeComponent }
]

When angular is done rending our HomeComponent, the user is ready to start interacting with other features modules of the application. We can do our user so well by preloading some of this modules in the background with some simple configuration.

Enabling Preloading

To enable preloading we need to pass a preloading strategy into forRoot.

@NgModule({ 
bootstrap: [HomeComponent],
imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })]
})

And the preloadingStrategy came from the ‘@angular/router’ so you will need to import it.

import { PreloadAllModules } from ‘@angular/router’;

Custom Preloading Strategy

The latest version of the router ships are in two strategies: preload nothing and preload all modules, but you can provide your own. And it is actually a lot simpler that it may seem. For instance, start loading the rest of the modules in 5s after app is loaded:

export class CustomPreloadingStrategy implements PreloadingStrategy{preload(route: Route, fn: () => Observable<boolean>):        Observable<boolean> {
return Observable.of(true).delay(5000).flatMap( (_:boolean)=>fn());
}
}

We can explicitly setup a preloader by telling angular which module we want to preload with this simple configuration data: {preload: true}.

export const routes: Routes = [   
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'shop', loadChildren: './shop/shop.module#ShopModule',
data: {preload: true} },

{ path: '**', component: HomeComponent }
]

having a preloadStratagies class let’s call it PreloadSelectedModules.

export class PreloadSelectedModules implements PreloadingStrategy { 
preload(route: Route, load: Function): Observable<any> {
return route.data && route.data.preload ? load() : of(null);
}
}

The preload method takes two parameters: a route and the function that actually does the preloading. In it, we can check if the preload property is set to true. And if it is, we call the load function.

Alright!!! as you can see, the angular routing architecture is very huge, flexible, and fantastic. I know they’re a lot of things we can still do with it. next week we’ll be doing something a bit more advance; we will be talking about how Angular detect’s changes and what makes it awesome. stay tune! subscribe and don’t forget to drop your comments then share.

--

--

Alex Onozor
alexonozor

Software Consultant, JavaScriptor, Web evangelist. Open source contributor. Software Architect.