John
John

Reputation: 565

Angular Lazy Loading Submodule

I have an application which uses lazy loading in multiple levels. The initial path of '/' is caught in the main app.routes and redirected to a lazy loaded module. That module also has its own submodule-1.routes and is just a container for other feature modules. In the submodule-1.routes, I am lazy loading the feature module. From what I can tell it seems that the modules are not being lazy loaded.

I have tried to create the routes in submodule-1 itself, and lazy load the feature modules from there but that hasnt helped.

Below is the folder structure

app
app.module.ts
app.routing-module.ts
-modules
--login
---login.module.ts
---login-routing.module.ts
---pages
----login-user
-----login-user.module.ts(LoginUserPageModule)
-----login-user-page.ts(LoginUserPage)
--signup
---signup.module.ts
---signup-routing.module.ts
----pages
-----signup-email
------signup-email.module.ts(SignUpEmailPageModule)
------signup-email-page.ts(SignUpEmailPage)

Below is my main routes in app.routes.ts:

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: '', redirectTo: 'login', pathMatch: 'full' },
  { path: 'signup-email', loadChildren: './modules/signup/signup.module#SignupModule' },
  { path: 'login', loadChildren: './modules/login/login.module#LoginModule' },

];

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

Signup Module

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { SignupRoutingModule } from './signup-routing.module';


@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    SignupRoutingModule
  ],
  exports:[]
})
export class SignupModule { }

SignupRoutes.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';

export const SIGNUP_ROUTES: Routes = [
    {
        path: '',
        loadChildren: './pages/signup-email/signup-email.module#SignupEmailPageModule'
    }
];


@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    RouterModule.forChild(SIGNUP_ROUTES)
  ],
  exports: [RouterModule]
})
export class SignupRoutingModule { }

SignupEmailPageModule

import { SignupEmailPage } from './signup-email.page';

const routes: Routes = [
  {
    path: '',
    component: SignupEmailPage
  }
];

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule
    ,RouterModule.forChild(routes)
  ],
  declarations: [SignupEmailPage]
})
export class SignupEmailPageModule {}

Login Module

@NgModule({
  declarations: [],
  imports: [
    LoginRoutingModule
  ],
  providers:[
  ]
})
export class LoginModule { }

LoginRoutes

export const LOGIN_ROUTES: Routes = [
    {
        path: '',
        loadChildren: './pages/login-user/login-user.module#LoginUserPageModule'
    }
];


@NgModule({
  declarations: [],
  imports: [
    RouterModule.forChild(LOGIN_ROUTES)
  ],
  exports: [RouterModule]
})
export class LoginRoutingModule { }

LoginUserPageModule

const routes: Routes = [
  {
    path: '',
    component: LoginUserPage
  }
];

@NgModule({
  imports: [
    IonicModule,
    RouterModule.forChild(routes),
    SharedModule
  ],
  declarations: [LoginUserPage]
})
export class LoginUserPageModule {}

Since the default path of '/' is being directed to login which is working, i expect the signup module to be lazy loaded, and visible only once. However, below is the image that i see from Augury on the initial load of the application which makes it seem like both LoginModule and SignupEmailModule are being loaded multiple times and not lazy loaded at all. As a result, I see the LoginUserPage and SignupEmailPage already loaded as in the image below from Augury.

Augury Representation showing the modules/pages already loaded

After removing the the { preloadingStrategy: PreloadAllModules } from app.routing.ts. I do see that the modules are now loaded lazily, however, when I access each of the lazy loaded modules, I see an extra 'lazy' node in the Augury graph as below. I'm not sure why that is, and if it should be there ?

Also, whenever a lazyloaded route is loaded, the other route goes back to showing as lazy, should it not just stay loaded from that point on ? Why does it go back to showing as 'lazy' in the graph, almost as if it hasnt been loaded.

Augury graph after accessing the default path which is also lazy loaded Image after access the default path which is also lazy loaded

Augury graph after accessing the lazy loaded route of 'signup' page Image after accessing the lazy loaded route of 'signup-email'

Upvotes: 0

Views: 2657

Answers (1)

thomi
thomi

Reputation: 1697

In your app.routes.ts you set preloadingStrategy: PreloadAllModules, this means your modules are being preloaded. So instead of loading your modules when they are first requested (lazily), the modules get loaded asynchronously in the background. It's kind of an in between strategy between eager and lazy loading but it means that all your modules get loaded in the end. From the documentation:

After each successful navigation, the router looks in its configuration for an unloaded module that it can preload. Whether it preloads a module, and which modules it preloads, depends upon the preload strategy.

The Router offers two preloading strategies out of the box:

  • No preloading at all which is the default. Lazy loaded feature areas are still loaded on demand.
  • Preloading of all lazy loaded feature areas.

Upvotes: 3

Related Questions