AngularM
AngularM

Reputation: 16648

My angular 2 app takes a long time to load for first time users, I need help to speed it up

Below I have pasted in my app.ts file.

I'm using angular2, with firebase and typescript.

Is the reason its slow because I have a lot of routes and I'm injecting a lot of files?

Also, my app works fine its just for first time users visiting the homepage I have this issue for.

I'm not sure if the bootstrap can be improved at the bottom or if I'm doing anything wrong.

This is my app.ts file:

import {Component, bind, provide, Injectable} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser'
import {NgIf} from 'angular2/common';
import {Router, Location, ROUTER_BINDINGS, RouterOutlet, RouteConfig, RouterLink, ROUTER_PROVIDERS, APP_BASE_HREF, CanActivate, OnActivate,
    ComponentInstruction} from 'angular2/router';
import {HTTP_PROVIDERS, Http, Headers} from 'angular2/http';
import {ANGULAR2_GOOGLE_MAPS_PROVIDERS} from 'angular2-google-maps/core';
import {enableProdMode} from 'angular2/core';
enableProdMode();

import {LoggedInRouterOutlet} from './interceptor';

import {AuthService} from './services/authService/authService';
import {SocialService} from './services/socialService/socialService';
import {UserService} from './services/userService/userService';
import {OrganisationService} from './services/organisationService/organisationService';
import {NotificationService} from './services/notificationService/notificationService';
import {EmailService} from './services/emailService/emailService';

import {UserProfile} from './models/profile/profile';
import {Organisation} from './models/organisation/organisation';

import {HeaderNavigation} from './components/header/header';
import {HeaderNavigationLoggedIn} from './components/header/headerNavigationLoggedIn';
import {HeaderNavigationLoggedInCompany} from './components/header/headerNavigationLoggedInCompany';
import {Footer} from './components/footer/footer';
import {SideMenuCompany} from './components/header/sideMenuCompany';
import {SideMenuUser} from './components/header/sideMenuUser';
import {Splash} from './components/splash/splash';

import {CreateJob} from './components/createJob/createJob';
import {SearchJobs} from './components/searchJobs/searchJobs';
import {Login} from './components/login/login';
import {Applications} from './components/applications/applications';
import {Register} from './components/register/register';
import {ForgotPassword} from './components/forgotpassword/forgotpassword';
import {ChangePassword} from './components/changepassword/changepassword';
import {ChangeEmail} from './components/changeemail/changeemail';
import {SocialRegister} from './components/socialregister/socialregister';
import {Admin} from './components/admin/admin';
import {Contact} from './components/contact/contact';
import {SearchUsers} from './components/searchusers/searchusers';

import {Jobs} from './components/job/jobs';
import {CompanyProfile} from './components/company/company';
import {Home} from './components/home/home';
import {Dashboard} from './components/dashboard/dashboard';
import {Profile} from './components/profile/profile';
import {UserApplications} from './components/userApplications/userApplications';

@Component({
    selector: 'app',
    providers: [UserService, UserProfile, OrganisationService, Organisation],
    template: `

        <Splash *ngIf="isLoggedIn"></Splash>    

        <HeaderNavigation *ngIf="!isLoggedIn"></HeaderNavigation>       

        <HeaderNavigationLoggedIn *ngIf="isLoggedIn && isUserLogin"></HeaderNavigationLoggedIn>
        <HeaderNavigationLoggedInCompany *ngIf="isLoggedIn && isCompanyLogin"></HeaderNavigationLoggedInCompany>

        <SideMenuCompany *ngIf="isLoggedIn && isCompanyLogin"></SideMenuCompany>
        <SideMenuUser *ngIf="isLoggedIn && isUserLogin"></SideMenuUser>

        <div class="content">
            <router-outlet></router-outlet> 
        </div>     
    `,
    directives: [RouterOutlet, RouterLink, Splash, HeaderNavigation, HeaderNavigationLoggedIn, NgIf, HeaderNavigationLoggedInCompany, SideMenuCompany, SideMenuUser, Footer, LoggedInRouterOutlet]
})

@RouteConfig([
    { path: '/', component: Home, as: 'Home', data:{title: 'Welcome Home'}},
    { path: '/home', component: Home, as: 'Home', useAsDefault: true},
    { path: '/login', component: Login, as: 'Login' },  
    { path: '/register/:id', component: Register, as: 'Register' },
    { path: '/forgotpassword', component: ForgotPassword, as: 'ForgotPassword' },
    { path: '/dashboard', component: Dashboard, as: 'Dashboard' },
    { path: '/search', component: SearchJobs, as: 'Search' },   
    { path: '/profile', component: Profile, as: 'Profile' },
    { path: '/settings', component: CompanyProfile, as: 'Settings' },
    { path: '/jobs', component: Jobs, as: 'Jobs' },
    { path: '/password', component: ChangePassword, as: 'Password' },
    { path: '/email', component: ChangeEmail, as: 'Email' },
    { path: '/applications', component: Applications, as: 'Applications' },
    { path: '/socialRegister/:id', component: SocialRegister, as: 'SocialRegister' },
    { path: '/socialRegister', component: SocialRegister, as: 'SocialRegister' },
    { path: '/applys', component: UserApplications, as: 'Applys' },
    { path: '/contact', component: Contact, as: 'Contact' },
    { path: '/searchTeachers', component: SearchUsers, as: 'SearchUsers' },
    { path: '/createJob', component: CreateJob, as: 'CreateJob' },
    { path: '/adminmarkchris2016', component: Admin, as: 'AdminMarkChris2016' },

    { path:'/**', redirectTo: ['Home']}
])

@Injectable()

export class AppComponent {
    router: Router;
    location: Location;
    authService: AuthService;
    userService: UserService
    isLoggedIn: boolean = false;
    isCompanyLogin: boolean = false;
    isUserLogin: boolean = false;
    userProfile: UserProfile;   

    constructor(_router: Router, _location: Location, _authService: AuthService, _userService: UserService, _userProfile: UserProfile){ 
        this.router = _router;
        this.location = _location;
        this.authService = _authService;
        this.userService = _userService;
        this.userProfile = _userProfile;

        this.isUserLoggedIn(this.location.path());

        //On refresh
        this.router.subscribe((currentRoute) => {
            this.isUserLoggedIn(currentRoute);
        })  
    }

    isUserLoggedIn(currentRoute): void{ 
        this.authService.checkIfLoggedIn().then((response) => { 
            this.isLoggedIn = response

            if(this.isLoggedIn){
                this.isUserOrganisationOrTeacher();                 
            }   

            if(currentRoute.substring(0, 14) == "socialRegister" || currentRoute == "socialRegister" || currentRoute == "home" || currentRoute == "contact" || currentRoute == "" || currentRoute == "forgotpassword" || currentRoute == "login" || currentRoute.substring(0, 8) == "register"){
                this.isCompanyLogin = false;
                this.isUserLogin = false;
                this.isLoggedIn = false;
            }           
        });  
    }

    isUserOrganisationOrTeacher(): void{
        this.userService.checkIfProfileExists().then((response) => {
            this.isCompanyLogin = false;
            this.isUserLogin = false;       

            if(response){
                this.isUserLogin = true;
                this.isCompanyLogin = false;
            }else{
                this.isCompanyLogin = true; 
                this.isUserLogin = false;                   
            }
        }); 
    }       
}

bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue: '/'}), HTTP_PROVIDERS, AuthService, SocialService, UserService, EmailService, OrganisationService, NotificationService, ANGULAR2_GOOGLE_MAPS_PROVIDERS]);

Upvotes: 44

Views: 71665

Answers (6)

jcdsr
jcdsr

Reputation: 1151

The main issue is zone.js on polyfills, Zone.js slowdown the app considerable

Upvotes: 1

Thierry Templier
Thierry Templier

Reputation: 202296

To have something ready for production (and speed it up), you need to package it.

I mean transpiling all files into JavaScript ones and concat them the same way Angular2 does for example. This way you will have several modules contained into a single JS file. This way you will reduce the number of HTTP calls to load your application code into the browser.

As a matter of fact, for the following configuration of SystemJS, you will have one call per module (it's suitable for development but not really efficient in production):

    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/boot')
            .then(null, console.error.bind(console));
    </script>

This answer could give hints about how module resolution works:

You can do this packaging using Gulp and its plugins:

See the following answers:

Upvotes: 19

Georgios
Georgios

Reputation: 1483

Another possibly approach to speed up your app is to use Lazy Loading

That way, your appModule will reduce the imports and the modules will be called on demand.

Upvotes: 1

Nidhin David
Nidhin David

Reputation: 2474

Though late, for people comming here now...if you are using angular2+ then try

ng build --prod --env=<staging or prod or your env file>

It will do AoT, bundling cache busting and minification all in one command. More deatils can be found in Angular official website in ng build section. In my case one of the chunk was actually 2.4MB which was reduced to 450+KB but after including --prod it was further reduced to 200+KB

Good size for an app depends. Angular2 has the concept of lazy loading of code or chunking. You can split your app into chunks (like admin UI and user UI) and load them on demand so that the entire app need not be loaded initially which will help in reduced load time. The following articles could be of extra help:

Upvotes: 7

David Herod
David Herod

Reputation: 794

I ran into this same problem, basically you just need to run the webpack build in production mode.

To do this install webpack globaly npm install webpack -g Once installed, run webpack -p from your apps root directory. This brought my file size down from over 5MB to about 700KB

Upvotes: 6

Oleg
Oleg

Reputation: 9359

Your problem is most probably related to file size delivered to client. 6.9MB is huge both in terms of network and parsing/evaluation time.

Suggestions:

  1. Minify your application
  2. Split it into multiple bundles (vendors.js, core.js, ...)

Upvotes: 5

Related Questions