Ionic Lazy Loading Bonuses

Ionic Lazy Loading is a meaty topic. There are a ton of options and with the proper configuration you can cause your loading to happen in just about any order you want. New to Ionic 3, Lazy Loading won’t reduce the workload, but it will allow you to do the work in sync with when your users want it to happen. I’m going to go through my preferred configuration and show you how to tune up the loading of your app.

The Basics

Lazy Loading starts with @IonicPage decorator. There are a ton of great options to read about on the the docs page here.

IonicPage is at the heart of thinking of your app’s pages as components and not a rigid structure. It provides a solid way to provide the complicated nested navigation native apps are known for. Placing the decorator on a page’s Typescript file and giving it a module file allows you to turn a page into it’s very own lazy loadable section.

Automatically we can remove any reference for the page on the app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home'; // <======== HERE

@NgModule({
  declarations: [
    MyApp,
    HomePage // <======== HERE
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage  // <======== AND HERE
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}

From now on when navigating to the page all you’ll have to do is give the navcontroller the name of the page as a string that you’ll specify in the page’s Module.ts file. This is basic lazy loading and I encourage you to read Mike Hartington's post on Lazy Loading over at the Ionic Blog.

Preloading

Basic lazy loading can do a lot for your page, especially if you have a lot of pages to load. It puts off the loading of the page to another time, only when the user needs the page. The user will still need to take the time to load the page though and time is lag. You can reduce that by introducing my new favorite lazy friend… PRELOADING!

First modify your app.module.ts with the preloadModules option on the IonicModule:

@NgModule({
  declarations: [
    MyApp
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp, {
      preloadModules: true
    })
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp
  ]
})
export class AppModule { }

Then add a priority option into the IonicPage decorator. Not adding one will simply default to low priority.

@IonicPage({
  priority: 'high'
})

Priority comes in three flavors:

  1. ‘high’ - Pages that are loaded first such as your Login, Home, and initial use pages. Basically anything that the user could get to in the first couple seconds.
  2. ‘low’ - The second stage of loading. Anything you specify as low, or don’t specify at all, will go here.
  3. ‘off’ - If a page is so rarely accessed that it doesn’t warrant the extra traffic needed to preload it. Acts like basic lazy loading, not a bad thing.

Sample flow

This diagram shows off this simple tier system. If I’m making an app that has a static root page I’ll turn lazy loading off as it adds nothing to the situation other than added complexity, but if it’s dynamic (like a login page) I turn it to high priority. After that the priorities are pretty self explanatory. Lastly I tend to turn it off for any pages that are complex and not often used. In this case the prize redemption form is a complex page that is going to be seen maybe a dozen or so times throughout the lifetime of the app. There’s no point to constantly having it sitting around ready to go. It will get traditionally lazy loaded when the user needs it.

Once you have that set the lazy loading comes when you want it. It’s a good deal more control over how your app loads and can give a much smoother feel to the user.

Encapsulated versus Shared Common Modules

When switching over an old app to a lazy loaded one you’ll probably encounter a lot of errors concerning the loading of your pipes, directive, and custom components. Since your pages are now separate modules you’ll need to import them into any page you want to use them in instead of just importing them in the App.module.ts like you did before.

Faced with this wall of red text many simply go for the easiest solution, but based on the size of your app you might want to use either encapsulated (Individual import statements) or shared common modules. A share common module is simply a file that contains references to all the other modules. Once you do that you only have to import that one file to get access to all of it's modules.

Long story short, you might want to use a common module file if you have a good deal of these type of modules, but if you only have a couple simply importing them into each page should suffice. Of course if you have far too many modules your file size can start to get quite large. At that point you might want to consider splitting up your common module into several smaller modules and importing them on a page by page basis.

Again, Mike Hartington is here with all the details.

Summary

Josh Morony’s new book Elite Ionic got me interested in this topic and there's a lot of other great material in there if you want to take your apps to the next level.

Lazy Loading has a lot of great options to fit your use case. Changing the details of the Ionic Page decorator can have interesting results and the preloading option is a small but powerful part of that. Using these options in a precise manner can greatly improve the feel of your app and reduce wait times.


Category: Development