Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Module with Multiple Component Gets Slow in loading

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.

like image 507
Prashant Kankhara Avatar asked Nov 21 '17 20:11

Prashant Kankhara


3 Answers

figure out what is wrong in your application without accessing the codebase is not easy, but I try the same giving some good advice that could help you.

Use @angular/cli

I've known many people that refused the use of a build tool, because webpack is already able to perform optimizations and uglifications if properly configured, but those people can't imagine how much powerful is this command:

ng build --prod

It will:

  1. Compile your code Ahead Of Time (AOT)
  2. Set the production flag
  3. Hash the name of the files (to prevent caching)
  4. Not produce sourcemaps
  5. Optimize your code (from Angular 5)
  6. Run UglifyJS on the code

So if you don't use @angular/cli, start using it. If you use it but you still didn't update your version, then update it.

Use source-map-explorer

source-map-explorer is a tool that let you know where the weight of your files come from. Maybe you imported a whole library but you just needed few functions? You can discover it through this tool.

Chrome is your friend

Another powerful tool which is often ignored is the Chrome Developer Tool. You don't need to install anything, just press F12, click on the Performance tab and start profiling.

Maybe you used a heavy sync function that's slowing down all the application? Maybe there's a function that needs some optimization? You can discover it, after your profiling you can see where your application takes more time, and clicking on the Call tree tab you can discover what's the name of that function and what's the source.

For similar purposes you can also check webpagetest.org.

Use a service worker

A well known way to speed up your application is using a service worker. You can read an interesting article clicking here.

The idea is to apply the PRPL pattern to Angular (which is a pattern that aims to optimize the parsing and the executation in order to achieve interactivity in low times through aggressive code-splitting and caching).

I hope some of my hints could lead you in the right direction. Let me know about it

like image 101
Cristian Traìna Avatar answered Sep 21 '22 15:09

Cristian Traìna


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.

like image 42
Janith Widarshana Avatar answered Sep 19 '22 15:09

Janith Widarshana


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

like image 22
Rahul Singh Avatar answered Sep 17 '22 15:09

Rahul Singh