/ ionic

Ionic 3 - Lazy Loading Pages

There are a variety of ways to incorporate lazy loading within your Ionic applications. Here's a video version of this article if you prefer:

Eager Loading

Let's start by looking at how we load a page without lazy loading. Inside of our main app.module.ts we add our Page to both the declarations and entryComponents array.

import { MyApp } from './app.component';
import { HomePage } from './../home/home.component';

@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  //Omitted
  entryComponents: [
    MyApp,
    HomePage
  ]
})

If we had a list of pages in our application, we'd have to declare all of them at runtime. In a complex production application, we'd have numerous pages and other things happening when we first open our app, all of which impacts loading performance.

You can see that the entire main.js bundle is sent down the wire when our application is initiated:

https://i.imgur.com/cUdgUAe.png

Lazy Loading - Feature Modules

In order for the best experience, we should aim to get our application on screen as quick as possible. This can be achieved by only loading the necessary components whenever they're required.

Let's make our Home component into a feature module by adding a home.module.ts into src/pages/home:

import { NgModule } from '@angular/core';
import { HomePage } from './home';
import { IonicPageModule } from 'ionic-angular';

@NgModule({
    imports: [
        IonicPageModule.forChild(HomePage)
    ],
    exports: [],
    declarations: [HomePage],
    providers: [],
})
export class HomeModule { }

Notice that I've also added the IonicPageModule.forChild(HomePage) here. This allows us to navigate to component(s) by routes, and thereby also gives us the ability to URL deep-link.

The next thing to do is add the @IonicPage() decorator to our HomePage. Our HomePage now looks like this:

import { Component } from '@angular/core';
import { NavController, IonicPage } from 'ionic-angular';

@IonicPage()  
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
...
}

We can also define custom URL deeplinks within the configuration of our @IonicPage, but that's an article for another time!

Because of our setup, we can now navigate to different pages within our application via a string rather than an imported component.

Currently, our root component is defined in app.component.ts like so:

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage: any = HomePage;
}

We can now change our rootPage to:

rootPage: string = 'HomePage';

This will navigate the user to the HomePage like before, but we've not imported it inside of our component.

https://i.imgur.com/abBNCNn.png

Notice the difference in this image, we're now looking at a main.js and a 1.main.js - two separate bundles. This means that each time we ask for a Page that we've declared as an @IonicPage(), we're getting a new bundle.

We're not limited to just loading the rootPage like this, the same works for our NavController. If we wanted to navigate a user to a new page, the syntax looks like this:

this.navCtrl.push('PageName');
Conclusion

Use lazy loading where possible, as this allows us to have a significant performance increase over eagerly loaded component(s). The implementation is still in the early stages of development and may not be suitable in all scenarios as of yet, but it's worth the speed increase in larger apps.

Paul Halliday

Progress Telerik Developer Expert. Course author with students in 110+ countries. BSc (Hons) Computer Science @ UoS. Google accredited Mobile Site professional.

Read More