Pre-load Angular Modules🥳
Tags: angular, typescript, javascript, performance
Published: 2022-01-15 09:03:29

## Preloading
**1.** In preloading, feature modules are loaded in background asynchronously. In preloading, modules start loading just after application starts.
**2.** When we hit the application, first **AppModule** and modules imported by it, will be loaded eagerly. Just after that modules configured for preloading is loaded asynchronously.
**3.** Preloading is useful to load those features which are in high probability to be visited by user just after loading the application.
**4.** To configure preloading, angular provides `preloadingStrategy` property which is used with `RouterModule.forRoot` in routing module. Find the code snippet.

```
@NgModule({
  imports: [ 
      RouterModule.forRoot(routes,
      {
        preloadingStrategy: PreloadAllModules
      }) 
  ],
  ------
})
export class AppRoutingModule { }
```
**5.** To configure preloading features modules, first we will configure them for lazy loading and then using Angular in-built **PreloadAllModules** strategy, we enable to load all lazy loading into preloading modules.
**6.** Using PreloadAllModules strategy, all modules configured by `loadChildren` property will be preloaded. The modules configured by `loadChildren` property will be either lazily loaded or preloaded but not both. To preload only selective modules, we need to use custom preloading strategy.
**7.** Once we configure `PreloadAllModules` strategy, then after eager loading modules, Angular searches for modules applicable for preloading. The modules configured by `loadChildren` will be applicable for preloading. We will take care that these feature modules are not imported in application module i.e. `AppModule`.
**8.** We can create custom preloading strategy. For this we need to create a service by implementing Angular `PreloadingStrategy` interface and override its preload method and then configure this service with `preloadingStrategy` property in routing module. To select a module for custom preloading we need to use data property in route configuration. data can be configured as `data: { preload: true }` for selective feature module preloading.

here we will use in-built preloading strategy i.e. `PreloadAllModules` strategy. Find the example.
Module and routing module for feature 1:
**country.module.ts**
 
```
import { NgModule }   from '@angular/core';
import { CommonModule }   from '@angular/common';
import { ReactiveFormsModule }    from '@angular/forms';
import { CountryComponent }  from './country.component';
import { CountryListComponent }  from './country-list/country.list.component';
import { CountryService } from './services/country.service';
import { CountryRoutingModule }  from './country-routing.module';

@NgModule({
  imports: [     
        CommonModule,
	ReactiveFormsModule,
	CountryRoutingModule
  ], 
  declarations: [
	CountryComponent,
	CountryListComponent
  ],
  providers: [ CountryService ]
})
export class CountryModule {
  constructor() {
    console.log('CountryModule loaded.');
  }
} 
```
**country-routing.module.ts**

```
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CountryComponent }  from './country.component';
import { CountryListComponent }  from './country-list/country.list.component';

const countryRoutes: Routes = [
	{ 
	  path: '',
          component: CountryComponent,
          children: [ 
	    {
	      path: 'country-list',
	      component: CountryListComponent
	    }  
	  ]
	}	
];

@NgModule({
  imports: [ RouterModule.forChild(countryRoutes) ],
  exports: [ RouterModule ]
})
export class CountryRoutingModule { }
```
Module and routing module for feature 2:
**person.module.ts**

```
import { NgModule }   from '@angular/core';
import { CommonModule }   from '@angular/common';
import { ReactiveFormsModule }    from '@angular/forms';
import { PersonComponent }  from './person.component';
import { PersonListComponent }  from './person-list/person.list.component';
import { PersonService } from './services/person.service';
import { PersonRoutingModule }  from './person-routing.module';

@NgModule({
  imports: [     
    CommonModule,
    ReactiveFormsModule,
    PersonRoutingModule
  ], 
  declarations: [
    PersonComponent,
    PersonListComponent
  ],
  providers: [ PersonService ]
})
export class PersonModule { 
  constructor() {
    console.log('PersonModule loaded.');
  }
}
```

**person-routing.module.ts**

```
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { PersonComponent }  from './person.component';
import { PersonListComponent }  from './person-list/person.list.component';

const personRoutes: Routes = [
	{ 
	  path: '',
          component: PersonComponent,
	  children: [ 
	    {
	      path: 'person-list',
	      component: PersonListComponent
	    }
	  ]
	}  
];

@NgModule({
  imports: [ RouterModule.forChild(personRoutes) ],
  exports: [ RouterModule ]
})
export class PersonRoutingModule { }
```
Now find the `AppModule` and `AppRoutingModule`.
**app.module.ts**

```
import { NgModule }   from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }  from './app.component';
import { AddressComponent }  from './address.component';
import { PageNotFoundComponent }  from './page-not-found.component';
import { AppRoutingModule }  from './app-routing.module';

@NgModule({
  imports: [     
    BrowserModule,
    AppRoutingModule
  ],
  declarations: [
    AppComponent,
    AddressComponent,
    PageNotFoundComponent
  ],
  providers: [ ],
  bootstrap: [ AppComponent ]
})
export class AppModule { 
  constructor() {
     console.log('AppModule loaded.');
  }
}
```
**app-routing.module.ts**

```
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { PreloadAllModules } from '@angular/router';
import { AddressComponent } from './address.component';
import { PageNotFoundComponent } from './page-not-found.component';

const routes: Routes = [
   {
      path: 'country',
      loadChildren: () => import('./country/country.module').then(mod => mod.CountryModule)
   },
   {
      path: 'person',
      loadChildren: () => import('./person/person.module').then(mod => mod.PersonModule)
   },
   {
      path: 'address',
      component: AddressComponent
   },
   {
      path: '',
      redirectTo: '',
      pathMatch: 'full'
   },
   {
      path: '**',
      component: PageNotFoundComponent
   }
];

@NgModule({
   imports: [
      RouterModule.forRoot(routes,
         {
            preloadingStrategy: PreloadAllModules
         })
   ],
   exports: [
      RouterModule
   ]
})
export class AppRoutingModule { } 
```

We can see in the `AppRoutingModule` that we are using PreloadAllModules strategy for preloading. The module configured by `loadChildren` i.e. `CountryModule` and `PersonModule` will be preloaded.
**Output**
When we hit the application for first time, we can see following logs in browser console.

```
AppModule loaded.
Angular is running in the development mode. Call enableProdMode() to enable the production mode.
CountryModule loaded.
PersonModule loaded.

```
We can observe that application started after loading `AppModule` and then application preloaded `CountryModule` and `PersonModule`.

Checkout to main blog [Angular Module Loading strategies
](https://dev.to/krishna7852/angular-module-loading-eager-lazy-and-preloading-3jj4)