Skip to content

Angular Module Lazy Loading like a Pro

Posted in Javascript, and Personal

Lemme begin by saying, I’m sorry for all the frustration you’ve had to go through before arriving here (assuming you found this article via search results.) I’ve been there before, and I hope this article clears all the confusions you came here with. Angular Module Lazy Loading, when understood, is simple.

Angular Universal Server Side Rendering is now easier. See how to deploy your SSR in production.

Except many articles assume readers know so much or the readers are so fresh the examples make no real-world sense.

In this article, we consider this scenario:

  • You have an Angular 5 project.
  • Which comes with the default, AppModule (src/app/app.module.ts)
  • In addition, you’ve created two modules
    • The AuthModule(src/app/auth/auth.module.ts) which is responsible for all your authentication needs i.e login, register, forgot password, etc.
    • And the AccountModule(src/app/account/account.module.ts) which is responsible for all user account related stuff i.e change password, update user profile, etc. This module requires authentication to access.

Now, let’s say we want to lazy load the AuthModule and AccountModule. How would we go about it?

Let’s do it then.

Our AppModule & app.routing.ts

Shall we cut to the meat (code) right away?

Here’s our typicalapp.module.ts file.

And then our typical app.routing.ts will be like this:

Honestly, we’re done. You can move on with your life.

That’s all it takes to do lazy loading in Angular. You use the loadChildren option and point to the module file (without the extension name, namely .ts) and reference the exported name in the module file, namely, the AuthModule after a #

Done.

When you ng serve or ng build --prod you should see the modules as chunks. Like this:

Modules Lazy Loading Chunks
Modules Lazy Loading Chunks

The highlighted lines are the are the chunks created automatically by Angular. These chunks WILL be loaded ONLY when any component from that module is referenced. It happens automatically.

AuthModule‘s routing as example

When you’re using the Lazy Loading approach, the loaded module’s route should have '' path in there to have it loaded.

For example, using the auth-module.routing.ts:

You might go in to throw in any Authentication guard you want. For example, using account-module.routing.ts as example:

Conclusion

I think the above provides a typical setup of an application and how the lazy loading is implemented. Lemme know of any questions you might have below in the comments.

See you in the next one.

 

  • polyglot

    I have my app cut into multiple modules and it works but I keep running into problems when trying to make one of them lazy loaded. I suspect I do not have routes they way that is required. BUT…
    A big problem is that all the lazy load tutorials I have seen (including this one), assume that you have put some of the routes into modules using ‘forChild’.
    IS THIS REQUIRED? If so, which routes MUST be put into the module? Are there rules about how the routes MUST be set up?

    I.E. I still have all my routes in the app-routing module (which works fine w/o lazy load).
    Can I not do this if I want to use lazy-loading?

    • What problem exactly do you run into trying to make one lazy load? Any errors?

      About the

      > IS THIS REQUIRED?

      You might wanna consider this part of the article below:

      “Since non-lazy loaded modules are merged, the providers you specify in the forRoot will be available for the entire applications. But as lazy-loaded modules have their own injectors, the providers you specify in the forChild will only be available for injection inside this lazy-loaded module.” – https://blog.angularindepth.com/avoiding-common-confusions-with-modules-in-angular-ada070e6891f

      In other words, your entire application has one forRoot() at the AppModule level. You can have as many forRoot()’s, but it defeats the purpose why the function exists.

      > Am I not allowed to keep them all in app-routing module if I want to use lazy-loading?

      In fact, you can put your routes wherever you want, as long as you export and reference them from and at the right places respectively.

      Only keep in mind that, the components/modules you want to lazy load, do not include it in your AppModule, as they’ll not be lazy loaded. Use the approach as shown in the article. That way, the module is only loaded when that route is hit.

      About the routes not matching, I had a similar issue, as I didn’t start with lazy loading in mind. I just took time to rethink what I want my routes to be, and put each lazy loaded module behind one route endpoint. So the AuthModule is available at /auth/ and so on.

      • polyglot

        I had several different errors (that were all discussed on stack overflow).
        But, I think the key is something that bothered me when I tried to change a route to use lazy load. Because all my routes are “flat”, i.e. not “child” routes, any route I wanted to change meant that I was replacing a reference to a component with a reference to a module. I kept wondering how the route would know which component to use!
        So, that is why I think that you probably MUST use child routes, and move them to the lazy module, so that there is a default route for the module that in effect specifies the component.

        • > Can you show a demo of lazy loading where all the routes are still in the app-routing.module (i.e. not in the lazy module)?

          No, that will defeat the whole idea of Lazy Loading, and lazy loading won’t work, *because*, if the component is pointed to when the application is bootstrapped in the app routing, then there won’t be lazy loading.

          • polyglot

            Ok, so that answers my original question “Is it required?”…and the answer is yes! thanks.