loading...

Lazy loading modules in Angular

achimoraites profile image Achilles Moraites Updated on ・3 min read

This has been posted on medium

As we develop our applications you might have noticed that the initial load speed gets slower as the application is being developed, especially on mobile devices and slow networks.

Imagine that you are developing an e-commerce web app that allows people to buy and sell products.

So you have pages for:

  • Searching products and people
  • Store page
  • Product page
  • User profile
  • Login/Registration

As a good developer you had organized the code in modules, but as the application grows the problem is only getting worse …

But first lets find out why.

What is happening?

Any modules you have used above are loaded on the application start even when they are not needed, this translates to:

  • Slow initial page load/speed: The perceived performance of the application is LOW.
  • That happens because the users have to wait for the browser to download all the modules, even those that are not needed at the given time!
  • Excessive network data usage: Mobile internet in many countries is expensive and slow. That means that visiting your application costs MONEY and TIME for each user!
  • Poor mobile performance: If you combine the above you have an application that is not mobile friendly.
  • Does not matter if you do RWD (Responsive Web Design) as the excessive volume that has to be downloaded and run on the application start is a sure way to make it unresponsive for a couple of seconds.
  • This becomes even worse on low end mobile devices…

Summarizing: loading almost everything on the application start is a terrible idea.

Why to lazy-load modules

To avoid all the bad things mentioned above we will need to lazy-load any module that has no need to be loaded on application start.
If the user of your application on the app start is on the search page there is no need to load any module that is no being used in the search page, as the user might never need to use them:

For example what happens if a user just searches for a product and goes to the product page?

The user will just need the modules for the search and product display, all the other modules have no need to be loaded at all.
How to lazy-load a module

Assuming we want to lazy-load the UserProfileModule

The module:

@NgModule({
    imports: [CommonModule,                        
         RouterModule.forChild([                   
         {path: '', component: UserProfileComponent}    
     ])],
    declarations: [UserProfileComponent]
})

export class UserProfileModule{}

The example above is a simple module with a single component that we will lazy-load.

Inside our app-routing.module.ts

const routes: Routes = [{  path: '', component: SearchComponent  },
  { path: 'products/:productId', component: ProductDetailComponent},
  { path: 'profile',   loadChildren:'./userprofile.module#UserProfileModule'}
];

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

Notice that we use loadChildren instead of component and we provide the path to the module and we add to it at the end a hash # followed with the module class name: in our example we append #UserProfileModule
How it works

  • The UserProfileModule is moved to a separate file when we build the application.
  • When the user navigates to the profile the UserProfileModule is being lazy-loaded: The module is downloaded and then used by the application.

If the user never visits the profile this module will never be loaded!
That’s it you have just lazy-loaded a module in Angular!
Summary

Module lazy-loading gives you more control on what modules will be loaded, allowing you to reduce the app bundle and the initial load times.

Module lazy-loading gives you awesome superpowers!

Discussion

pic
Editor guide