Last update on Wednesday, April 19th 2017

Ionic 3 New Pages Lazy Loading

Page Lazy Loading is awesome.
I never start a tuts like this, but f*** yea!

This new feature from Ionic 3 not only makes our code more concise but also avoid the hassle of typing every damn time the same paths in every Class!
Lazy Loading allows us to access Pages wherever we want by only using a string.

We are going to see how things were before and how they got improved.

The old way

First let's go to the terminal to create the Ionic app:

ionic start routy tabs --v2

This generates a normal Ionic 3 app with the following imports in the app.module.ts:

import { AboutPage } from '../pages/about/about';
import { ContactPage } from '../pages/contact/contact';
import { HomePage } from '../pages/home/home';
import { TabsPage } from '../pages/tabs/tabs';

@NgModule({
  declarations: [
    MyApp,
    AboutPage,
    ContactPage,
    HomePage,
    TabsPage
  ],
  .
  .
  .
  entryComponents: [
    MyApp,
    AboutPage,
    ContactPage,
    HomePage,
    TabsPage
  ]
})

Every time we create a Page, we need to add it there in the app.module.ts.

Same for the Main Component:

import { TabsPage } from '../pages/tabs/tabs';

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

When setting the rootPage property, an import of the Page is required.

Same trivial task for the navigation:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { AboutPage } from '../about/about';

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

  constructor(public navCtrl: NavController) {

  }

  ngOnInit() {
    this.navCtrl.push(AboutPage);
  }
}

Here we need to make an import of the AboutPage before being able to navigate to it, it's not awesome ...

A New Hope

As you can see, when creating an app, the generated Pages are not lazy loaded by default.
Let's start by creating one using this command in the terminal:

ionic g page options

Great!
Now we have a new OptionsPage created for us.

The Page Component is not only a Component anymore:

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

/**
 * Generated class for the Options page.
 *
 * See http://ionicframework.com/docs/components/#navigation for more info
 * on Ionic pages and navigation.
 */
@IonicPage()
@Component({
.
.
.
});

Ionic now requires a new Decorator in order to do the work : the @IonicPage.
One new Module is generated now, the OptionsModule:

import { NgModule } from "@angular/core";
import { IonicModule } from "ionic-angular";
import { Options } from "./options";

@NgModule({
  declarations: [Options],
  imports: [IonicModule.forChild(Options)],
  exports: [Options]
})
export class OptionsModule {}

This new Module will import the @IonicPage, export and declare it for us.
The only issue here is that the ionic generate command is not totally up-to-date.
The following line throws an error:

IonicModule.forChild(Options);
Property 'forChild' does not exist on type 'typeof IonicModule'.

So, we need to replace the IonicModule by the IonicPageModule.
This is how the code should be:

import { NgModule } from "@angular/core";
import { IonicPageModule } from "ionic-angular";
import { Options } from "./options";

@NgModule({
  declarations: [Options],
  imports: [IonicPageModule.forChild(Options)],
  exports: [Options]
})
export class OptionsModule {}

And that's all we need to do!
No more import in the app.module.ts or anywhere else!

Going back to the home.ts:

  ngOnInit() {
    this.navCtrl.push('Options');
  }

We only need to pass a string of where we want to go now!

The other pages (Home, About, Contact) can be recreated now.
We now have one DRY app.module.ts:

@NgModule({
  declarations: [
    MyApp
  ]
  .
  .
  .
  entryComponents: [
    MyApp
  ]
  .
  .
  .
})

Don't forget to make the conversion in the app.component.ts:

export class MyApp {
  rootPage:any = "Tabs";
  .
  .
  .
}

And in the tabs.ts:

export class Tabs {
  tab1Root = "Home";
  tab2Root = "About";
  tab3Root = "Contact";
  .
  .
  .
}

Conclusion

I'm lazy and always prefer to have less code, less imports, less paths to remember: The less, the better!
Importing every time the Ionic Pages can sometime kill the fun of developing with Ionic.
Now with Lazy Loaded Pages, we can just generate, sit back and profit.
It's one of the best feature from Ionic 3, however it's not (yet) mandatory and its architecture forces us to create a new module for each Page which in my opinion (the less, the better) and others is a big flaw.
Next thing to test will be the performance improvement!

Stay up to date


Join over 4000 other developers who already receive my tutorials and their source code out of the oven + other free stuff!