What is Lazy Loading (and why you should use it)?
Lazy loading is an Angular technique that allows you to load feature components asynchronously when a specific route is activated. This can add some initial performance during application bootstrap, especially if you have many components with heavy UI and complex routing.
Use lazy loading to decrease the startup time of your NativeScript application.
How does Lazy Loading work?
With lazy loading, the application is split into multiple
modules. There is the main module which in the context of
NativeScript application will hold the root components (usually
called app.module.ts
located in the
app
folder) and the featured modules which will be
loaded "on demand" after user interaction. Each module can
define multiple components, services, and routes.
Implementing Lazy Loading in NativeScript
In the following sections, we will create a simple Angular application using the Hello World template which by default has no lazy loaded modules. Then, we will add the featured lazy loaded HomeModule.
-
Create the Hello World Angular template
tns create my-app --ng cd my-app
-
Add a new folder to hold your
FeatureModule
along with all the components, services, routing tables of the module.A good practice is to use the name of the module as the name of the containing folder. For example, create a
feature
folder and addfeature.module.ts
and the needed components that will be part of the module (in our casefeature.component.ts
with the respective HTML and CSS files).my-app --app ----feature ------feature.component.css ------feature.component.html ------feature.component.ts ------feature.module.ts ------feature.routing.ts ------feature.service.ts
-
Create the routing table and the lazily loaded module
app/feature/feature.routing.ts
// app/feature/feature.routing import { NgModule } from "@angular/core"; import { Routes } from "@angular/router"; import { NativeScriptRouterModule } from "nativescript-angular/router"; import { FeatureComponent } from "./feature.component"; export const routes: Routes = [ { path: "", component: FeatureComponent } ]; @NgModule({ imports: [NativeScriptRouterModule.forChild(routes)], // set the lazy loaded routes using forChild exports: [NativeScriptRouterModule] }) export class FeatureRoutingModule { }
app/feature/feature.module.ts
// app/feature/feature.module.ts import { NativeScriptCommonModule } from "nativescript-angular/common"; import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core"; import { FeatureComponent } from "./feature.component"; // Import all components that will be used in the lazy loaded module import { FeatureService } from "./feature.service"; // Import all services that will be used in the lazy loaded module import { FeatureRoutingModule } from "./feature.routing"; // import the routing module @NgModule({ schemas: [NO_ERRORS_SCHEMA], imports: [ NativeScriptCommonModule, FeatureRoutingModule ], declarations: [FeatureComponent], // declare all components that will be used within the module providers: [ FeatureService ] // provide all services that will be used within the module }) export class FeatureModule { }
-
Add the lazily loaded module to the application routing table
app/app.routing.ts
// app/app.routing.ts import { NgModule } from "@angular/core"; import { NativeScriptRouterModule } from '@nativescript/angular'; import { Routes } from "@angular/router"; import { ItemsComponent } from "./item/items.component"; import { ItemDetailComponent } from "./item/item-detail.component"; const routes: Routes = [ { path: "", redirectTo: "/items", pathMatch: "full" }, { path: "items", component: ItemsComponent }, { path: "item/:id", component: ItemDetailComponent }, { path: "feature", loadChildren: () => import("./feature/feature.module").then(m => m.FeatureModule) }, // lazy loaded module ]; @NgModule({ imports: [NativeScriptRouterModule.forRoot(routes)], exports: [NativeScriptRouterModule] }) export class AppRoutingModule { }
-
Navigating to lazily loaded module
With all of the above steps implemented, you can start navigating to the default path of the lazily loaded module.
app/item/items.component.html
<!-- app/item/items.component.html --> <StackLayout class="page"> <!-- navigate to the default path in the lazy loaded module --> <Label text="Go to my Feature" [nsRouterLink]="['/feature']" class="h2 m-10"></Label> <ListView [items]="items" class="list-group"> <ng-template let-item="item"> <Label [nsRouterLink]="['/item', item.id]" [text]="item.name" class="list-group-item"></Label> </ng-template> </ListView> </StackLayout>
Benefits from using Lazy Loading
A real-life NativeScript application (like the Angular SDK Examples) can have hundreds of different components. Each component may have its route, services, and multiple featured components. Using lazy loading modules improves the startup time dramatically (in the case of SDK Examples app with up-to 5x better startup timings). Instead of having to load the hundreds of components at the application bootstrap, you can load just the landing module and load all other submodules lazily.