Preloading

So far, we have been discussing eager loading and lazy loading. Eager loading, in this case, has meant that we load the entire application at once. Lazy loading has been about us identifying certain modules as modules that we only load on demand, that is, they are lazy loaded. There is, however, something in between: preloaded modules. Why do we need something in between, though? Well, imagine that we know with a good certainty that a normal user will want to access the products module within 30 seconds after logging in. It makes sense to mark the products module as a module that should be lazy loaded. It would be even better if it could be loaded in the background right after login so that it is ready to go when the user navigates to it. That is exactly what preloading does for us. 

We enable preloading by issuing the following command:

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

This PreloadAllModules value preloads each and every lazy-loaded route, except for the ones guarded by the canLoad guard. This makes sense: the canLoad only loads if we are authenticated/authorized, or based on some other condition that we set up.

So, if we had a bunch of modules that were all set up as lazy, such as products, admin, categories, and so on, all of those would be loaded right after the initial boot based on PreloadAllModules. That might be good enough on a desktop. However, if you are on a mobile connection such as 3G, this might be way too heavy. At this point, we want better, more fine-grained control. What we can do is implement our own custom strategy for this. We need to do the following to do that:

  1. Create a service that implements PreloadingStrategy and the preload method.
  2. The preload() method must call the load() method, if it should be preloaded, or should return an empty Observable otherwise.
  3. Define whether a route should be preloaded, by using the data attributed on a route, or by using a service.
  4. Set the create strategy service as the value of preloadingStrategy.

For the first order of business, defining our service, we create it like this:

@Injectable()
export class PreloadingStrategyService implements PreloadingStrategy {
preload(route: Route, load: () => Observable<any>): Observable<any> {
if(route.data.preload) {
return
load();
} else {
return Observable.of(null);
}
}
}

We can see how we invoke the load method if our route.data contains the preload Boolean.

Now, for setting up the route correctly:

{
path: 'anotherlazy',
loadChildren: 'app/anotherlazy/anotherlazy.module#AnotherLazyModule',
data: { preload: true }
}

The data property has been set to an object containing our preload property.

Now for the last step. Let's make the RouterModule.forRoot() aware that this service exists:

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

In short, this is a very efficient way of ensuring the user has the best possible experience without succumbing to either eager loading, or having to wait for a lazy load.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset