Preloading
Strategies for Angular Modules
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995410/angular.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995411/profile_pic.jpg)
Angular RTP Meetup
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
Hey, Am Udhay (OO-dhy)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995433/angular_solidBlack__1_.png)
Agenda
- Single Module Angular App
- Multi Module Angular App
- Lazy loading
- Preloading Modules:
- All
- Selective
- Network based
- Quick link
- Discussion (Q/A)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/7375710/banner.png)
Single Module Angular App
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
- App contains only one module that has Components, Pipes, Directives and Services.
- It works great for small web application with five to ten pages.
Module
Components
Pipes
Directives
Multi Module Angular App
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
- App contains more than one module with App module being the root module. Each modules contains Components, Pipes, Directives and Services.
- It works great for Enterprise level applications
Root / Main
Home
Products
Cart
Payment
Orders
![](https://media1.giphy.com/media/6Cvzt6TBcFOne/giphy.gif)
Lazy loading
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
Lazy loading
- Loads Angular Module only when the route is visited / accessed.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
Root / Main
Home
Products
Cart
Payment
Orders
/home
/products
/cart
/billing
/orders
https://someonlinestore.com/
Lazy loading (Contd)
Create new Angular project
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
ng new someonlinestore --routing
ng generate module payment --route billing --module app.module
Create feature module (Angular takes care of lazy loading configuraiton)
Lazy loading (Contd)
Application's Root Module Routes look like:
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
const routes: Routes = [
{
path: 'billing',
loadChildren: () =>
import('./payment/payment.module').
then((m) => m.PaymentModule),
}
];
When User accesses https://someonlinestore.com/billing, Payment module gets loaded and their content painted on UI
Drawback of Lazy Loading
- If the bundle (Feature module) size is huge, it makes User to wait couple moments to load the page when the respective route is accessed.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
This can be fixed by Preloading the module that's huge in size based on different strategies. Let's dig into it more..
Preloading Strategy - All
Preload All Modules by setting preloadingStrategy router option as below:
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
@NgModule({
imports: [
RouterModule.forRoot(routes,
{ preloadingStrategy: PreloadAllModules }
),
],
exports: [RouterModule],
})
Preloading Strategy - Selective
Set Preload JSON parameter value to either true or false in the route. And update preloadingStrategy to SelectivePreloadStrategy (let's create it).
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
const routes: Routes = [
{
path: 'home',
loadChildren: () => import('./home/home.module').then((m) => m.HomeModule),
data: {preload: true}
},
{
path: 'about',
loadChildren: () =>
import('./about/about.module').then((m) => m.AboutModule),
data: {preload: false}
},
];
@NgModule({
imports: [
RouterModule.forRoot(routes, {preloadingStrategy: SelectivePreloadStrategy}),
],
exports: [RouterModule],
})
Preloading Strategy - Selective (Contd)
Create a Service class 'SelectivePreloadStrategy' & implement PreloadingStrategy Interface. Add logic within preload method that decides whether to preload module or not..
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, EMPTY } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SelectivePreloadStrategy implements PreloadingStrategy{
constructor() { }
preload(route: Route, load: () => Observable<any>): Observable<any>{
return route.data && route.data['preload'] ? load() : EMPTY;
}
}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
const routes: Routes = [
{
path: 'home',
loadChildren: () => import('./home/home.module').then((m) => m.HomeModule),
data: {preload: true}
},
{
path: 'about',
loadChildren: () =>
import('./about/about.module').then((m) => m.AboutModule),
data: {preload: false}
},
];
@NgModule({
imports: [
RouterModule.forRoot(routes, {preloadingStrategy: NetworkPreloadStrategy}),
],
exports: [RouterModule],
})
Preloading Strategy - Network Connection Based
Update preloadingStrategy to NetworkPreloadStrategy (let's create it).
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
import { Injectable } from '@angular/core';
import { PreloadingStrategy } from '@angular/router';
import { EMPTY, TimeoutError } from 'rxjs';
export declare var navigator;
@Injectable({
providedIn: 'root'
})
export class NetworkPreloadStrategy implements PreloadingStrategy{
constructor() { }
preload(route: import("@angular/router").Route, load: () => import("rxjs").Observable<any>): import("rxjs").Observable<any> {
return this.hasGoodNetworkConn() ? load() : EMPTY;
}
hasGoodNetworkConn() {
const conn = navigator.connection;
if(conn){
const connectionsToAvoid = ['2g', '3g'];
const connectionType = conn.effectiveType || '';
console.log(connectionType);
if(connectionsToAvoid.includes(connectionType)){
return false;
}
}
return true;
}
}
Preloading Strategy - Network Connection Based (Contd)
Decide preloading based on Network..
Preloading Strategy - Quick Links Strategy
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1255386/images/6995412/Twitter_Social_Icon_Circle_Color.png)
const routes: Routes = [
{
path: 'home',
loadChildren: () => import('./home/home.module').then((m) => m.HomeModule),
data: {preload: true}
},
{
path: 'about',
loadChildren: () =>
import('./about/about.module').then((m) => m.AboutModule),
data: {preload: false}
},
];
@NgModule({
imports: [
RouterModule.forRoot(routes, {preloadingStrategy: QuickLinkStrategy}),
],
exports: [RouterModule],
})
Using ngx-quicklink, the configuration is straightforward..
Import the QuicklinkModule in AppModule and add QuickLinkStrategy as Preloading strategy
Links
Twitter- https://twitter.com/AskUdhay
Check my previous talks - http://askudhay.com/