Angular Module with Multiple Component Gets Slow in loading

Viewed 15818

I have found a scenario which delays initiating my module in Angular 2. I am not an experienced guy in Angular. This is my first project. So, didn't know how to deal with this scenario:

I have created a small application in which there are various modules. Each module has 2-3 subcomponents. But my SignUp Module and MyAccount Module is the mixture of various components.

Below is the hierarchy of my application.

app
--Front-end
----videos
------Detail
--------videodetail.component.html
--------videodetail.component.ts
------List
--------list.component.html
--------list.component.ts
------videos.component.html
------videos.component.ts
------videos.routing.ts
------videos.module.ts
----article
------article.component.html
------article.component.ts
----front-end.routing.ts
----front-end.module.ts
----front-end.component.ts
----front-end.component.html
--signup
----stepone
------stepone.component.html
------stepone.component.ts
----steptwo
------steptwo.component.html
------steptwo.component.ts
----stepthree
------stepthree.component.html
------stepthree.component.ts
----stepfour
------stepfour.component.html
------stepfour.component.ts
----final
------final.component.html
------final.component.ts
----OneMore
------onemore.component.html
------onemore.component.ts
----signup.module.ts
----signup.component.ts
----signup.routing.ts
----signup.component.html app.module.ts app.component.ts app.component.html app.routing.ts

Below is the signup-routing.module.ts routing code for children.

const routes: Routes = [
    { path: '', component: SignupComponent },
    { path: 'terms', component: TermsComponent },
    { path: 'first', component: StepOneComponent },
    { path: 'second', component: SteptwoComponent },
    { path: 'third', component: StepthreeComponent },
    { path: 'third/:status', component: StepthreeComponent },
    { path: 'third/:status/:type', component: StepthreeComponent },
    { path: 'success', component: FinalComponent }

As requested, below is the constructor of SingupComponent and BaseComponent.

export class BaseComponent implements OnInit  {
    public SiteConfigurations: SiteConfigurations;
    public options: any
    constructor() {
        this.SiteConfigurations = new SiteConfigurations();
        var currentClass= this;
        window["SetDefaultImage"] = function(){}
        window["SetDefaultImage"]=function (event){
          currentClass.SetDefaultImageWithCurrentClass(event,currentClass);
        };
    }

    ngOnInit() {
      //  this.options = Baser
    }

    SetDefaultImageWithCurrentClass(event,currentClass) {
        event.target.src = currentClass.SiteConfigurations.EnvironmentConfigurations.siteURL+"assets/images/no-image.png";
    }
    SetDefaultImage(event) {
      this.SetDefaultImageWithCurrentClass(event,this);
    }
}

export class SignupComponent extends BaseComponent implements OnInit, OnDestroy {
constructor(router: Router, accountService: AccountService) {
    super();
    this.accountService = accountService;
    this.router = router; }

    ngOnInit(): void {
        this.packageType = this.getStepData("packageType");
        this.stepone = this.getStepData("stepone");
        this.steptwo = this.getStepData("steptwo");

        this.options = this.accountService.notificationService.options;
        this.clear = true;
    }
}

Below is my app-routing.module.ts code.

const routes: Routes = [
    {
        path: '', component: FrontEndComponent,
        children: [
        { path: 'home', loadChildren: './home/home.module#HomeModule' },
        { path: 'videos', loadChildren: './videos/videos.module#VideosModule' },
        { path: 'myaccount', loadChildren: './users/users.module#UsersModule', canActivate: [AuthGuard] },
        { path: 'signup', loadChildren: '../signup/signup.module#SignupModule' }]   
    } 
];

When I run my application and homepage gets loaded, when I click on SignUp for the first time it takes some time to execute the constructor of the signup.component.ts The reason I found is in the signup module there are various subcomponents which get load when the signup module is called for the first time (i.e. when the chunk file is generated). The same problem is with the AccountModule where around 8 to 10 subcomponents are used to show data in the user account dashboard.

It holds for some 2-3 seconds before the SignUp component's constructor and onInit method is called and then go to the server side to take data from the database. While other modules like videos, articles and rest other have only 2 and maximum 3 subcomponents and they are getting executed immediately.

6 Answers

Please read and understand about angular lazy loading. Following links may help you to solve your problem.

https://angularfirebase.com/lessons/how-to-lazy-load-components-in-angular-4-in-three-steps/

https://medium.com/@leekp/lazy-loading-with-angular-4-29c23792b7f4

https://angular-2-training-book.rangle.io/handout/modules/lazy-loading-module.html

As I can see your solution has routing for each modules. You must load them as follows on app-routing.module.ts

const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', component: HomeComponent },
  { path: 'signup', loadChildren: 'sighup/sighup.module#SignUpModule' },
  { path: 'front-end', loadChildren: 'front-end/front-end.module#FrontEndModule' },

];

This will prevent executing other modules when calling signup module.

Than signup routing can change as follows also. (it depends on your application)

const routes: Routes = [
    { path: '', component: SignupComponent },
children: [
    { path: 'terms', component: TermsComponent },
    { path: 'first', component: StepOneComponent },
    { path: 'second', component: SteptwoComponent },
    { path: 'third', component: StepthreeComponent },
    { path: 'third/:status', component: StepthreeComponent },
    { path: 'third/:status/:type', component: StepthreeComponent },
    { path: 'success', component: FinalComponent }
]
}

also set for sign up module in signup.components.html too.

If you feel that your app is getting slower due to large number of components . You might need to try lazy loading in Angular.

Lazy loading in Action

The above is a small lazy loaded component i have developed for my App.

Lazy loading modules helps us decrease the startup time. With lazy loading our application does not need to load everything at once, it only needs to load what the user expects to see when the app first loads. Modules that are lazily loaded will only be loaded when the user navigates to their routes.

More indepth of how to use Lazy loading Credits - https://angular-2-training-book.rangle.io/handout/modules/lazy-loading-module.html

First attach your signup routing file. sometes the route guards makes a component load slow. If there is any guard in the signup routing file then check by removing it

I had the same problem and found a native way to resolve it with PreloadAllModules class from the @Angular/router library. to do this, just configure your app-routing.module.ts file like this:

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

const routes: Routes = [
// app globals routes
]

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

export class AppRoutingModule { }

In addition to the Angular official doc I found this excellent article which could explain you more about this implementation

Hope that this could help you

Related