Ionic2 performance issue

ε祈祈猫儿з 提交于 2020-01-03 04:56:06

问题


My ionic2 app is taking like 15 seconds to start in a device. I tried all the recommendation (minify, uglify, enableProd, --prod --release, etc) My final apk is 4.3MB

The app doesn't have any image except from the icon and from the splashcreen, It has more less 20 screens, but just text and list and buttons (it's a payment app so nothing weird)

My package.json is:

{
  "name": "xxxxx",
  "author": "xxxx",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "2.2.1",
    "@angular/compiler": "2.2.1",
    "@angular/compiler-cli": "2.2.1",
    "@angular/core": "2.2.1",
    "@angular/forms": "2.2.1",
    "@angular/http": "2.2.1",
    "@angular/platform-browser": "2.2.1",
    "@angular/platform-browser-dynamic": "2.2.1",
    "@angular/platform-server": "2.2.1",
    "@ionic/cloud-angular": "^0.8.0",
    "@ionic/storage": "1.1.6",
    "@ngtools/webpack": "1.1.9",
    "angularfire2": "^2.0.0-beta.6",
    "firebase": "^3.6.4",
    "ionic-angular": "2.0.0-rc.4",
    "ionic-native": "2.2.11",
    "ionicons": "3.0.0",
    "rxjs": "5.0.0-beta.12",
    "zone.js": "0.6.26"
  },
  "devDependencies": {
    "@ionic/app-scripts": "^1.1.0",
    "@ngtools/webpack": "^1.1.9",
    "@types/request": "0.0.30",
    "ionic-minify": "^2.0.10",
    "typescript": "2.0.9"
  },
  "cordovaPlugins": [
    "cordova-plugin-whitelist",
    "cordova-plugin-statusbar",
    "cordova-plugin-splashscreen",
    "cordova-plugin-device",
    "ionic-plugin-keyboard",
    "phonegap-plugin-push"
  ],
  "cordovaPlatforms": [],
  "description": "xxxxx: An Ionic project"
}

Do you see any issue with the dependencies or with the plugins?

The minimized main.js file is 5.8MB.

My app.module is:

import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { NextPayments } from './payment/nextPayments/nextPayments';
import { Login } from './user/login/login';
import { SignUp } from './user/signup/signup';
import { Terms } from './user/terms/terms';
import { Contactus } from './user/contactus/contactus';
import { ChangeEmail } from './user/changeEmail/changeEmail';
import { ChangePassword } from './user/changePassword/changePassword';
import { ResetPassword } from './user/resetPassword/resetPassword';
import { PaymentInformation } from     './payment/paymentInformation/paymentInformation';
import { UnidadesList } from './payment/unidadesList/unidadesList';
import { UnidadInformation } from     './payment/unidadInformation/unidadInformation';
import { PaymentConfirmation } from './payment/paymentConfirmation/paymentConfirmation';
import { PaymentHistory } from './payment/paymentHistory/paymentHistory';
import { OneClickPayment } from './payment/oneClickPayment/oneClickPayment';
import { HistoryInformation } from './payment/historyInformation/historyInformation';
import { AddPayment } from './payment/addPayment/addPayment';
import { AccountList } from './account/accountList/accountList';
import { AddAccount } from './account/addAccount/addAccount';
import { AccountInformation } from './account/accountInformation/accountInformation';
import { EqualValidator } from './directives/equalValidator';
import { AngularFireModule } from 'angularfire2';
import { CloudSettings, CloudModule } from '@ionic/cloud-angular';

export const firebaseConfig = {
    apiKey: "xxxxxx",
    authDomain: "xxxxxxxx",
    databaseURL: "xxxxxxxxxx",
    storageBucket: "xxxxxxxx",
    messagingSenderId: "xxx"
}

const cloudSettings: CloudSettings = {
  'core': {
    'app_id': 'xxxxx'
  },
  'push': {
    'sender_id': 'xxxxx',
    'pluginConfig': {
      'ios': {
        'badge': true,
        'sound': true
      },
      'android': {
        'iconColor': '#921F67'
      }
    }
  }
};

@NgModule({
  declarations: [
    MyApp,
    NextPayments,
    PaymentInformation,
    Login,
    PaymentConfirmation,
    AddPayment,
    EqualValidator,
    AccountList,
    AddAccount,
    HistoryInformation,
    Terms,
    Contactus,
    PaymentHistory,
    AccountInformation,
    UnidadInformation,
    UnidadesList,
    SignUp,
    ResetPassword,
    OneClickPayment,
    ChangeEmail,
    ChangePassword
  ],
  imports: [
    IonicModule.forRoot(MyApp, {
      monthNames: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre' ],
      monthShortNames: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic' ],
      dayNames: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves',     'Viernes', 'Sabado' ],
      dayShortNames: ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab' ],
    }),
    AngularFireModule.initializeApp(firebaseConfig),
    CloudModule.forRoot(cloudSettings)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    NextPayments,
    PaymentInformation,
    Login,
    UnidadInformation,
    UnidadesList,
    PaymentConfirmation,
    AddPayment,
    Terms,
    Contactus,
    AccountList,
    AddAccount,
    AccountInformation,
    HistoryInformation,
    PaymentHistory,
    OneClickPayment,
    SignUp,
    ResetPassword,
    ChangeEmail,
    ChangePassword
  ],
  providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}]
})
export class AppModule {}

And my app.components:

import { Component, ViewChild } from '@angular/core';
import { Nav, Platform, AlertController, IonicApp, ToastController,     MenuController } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';

import { NextPayments } from './payment/nextPayments/nextPayments';
import { UnidadesList } from './payment/unidadesList/unidadesList';
import { PaymentHistory } from './payment/paymentHistory/paymentHistory';
import { PaymentInformation } from './payment/paymentInformation/paymentInformation';
import { Login } from './user/login/login';
import { ChangeEmail } from './user/changeEmail/changeEmail';
import { OneClickPayment } from './payment/oneClickPayment/oneClickPayment';
import { ChangePassword } from './user/changePassword/changePassword';
import { Contactus } from './user/contactus/contactus';
import { Terms } from './user/terms/terms';
import { Response } from './models/response';
import { Payment } from './models/payment';
import { Session } from './session/session';
import { Push, PushToken } from '@ionic/cloud-angular';
import { AccountList } from './account/accountList/accountList';
import { UserService } from '../app/user/userService';
import { ServerService } from './server/server.service';
import { LoadingController } from 'ionic-angular';
import { AccountService } from './account/accountService';
import { PaymentService } from './payment/paymentService';

declare var navigator: any;

@Component({
  templateUrl: 'app.html',
  providers: [Session, UserService, ServerService, PaymentService, AccountService]
})
export class MyApp {
  @ViewChild(Nav) nav: Nav;
  payment : Payment = new Payment();
  rootPage: any = Login;
  backButtonPressed: boolean = false;
  pages: Array<{title: string, component: any}>;

  constructor(public loadingCtrl : LoadingController, public paymentService     : PaymentService, public accountService : AccountService, public menuCtrl: MenuController, public toastCtrl: ToastController, private ionicApp : IonicApp, public platform: Platform, public serverService: ServerService, public session: Session, public push: Push, public userService: UserService, public alertCtrl: AlertController) {
    this.initializeApp();
    if(this.session.isAuth())
      this.rootPage = NextPayments;
    // used for an example of ngFor and navigation
    this.pages = [
      { title: 'Próximos Pagos', component: NextPayments },
      { title: 'Mis Unidades', component: UnidadesList },
      { title: 'Mis C.B.U.', component: AccountList },
      { title: 'Historial de Pagos', component: PaymentHistory },
      { title: 'Cambiar Email', component: ChangeEmail },
  { title: 'Cambiar Contraseña', component: ChangePassword },
  { title: 'Términos y Condiciones', component: Terms },
  { title: 'Contáctenos', component: Contactus },
  // { title: 'Configuración', component: Settings }
];

this.push.rx.notification()
    .subscribe((msg) => {
      let loader = this.loadingCtrl.create({
        content: "Obteniendo información..."
      });
      loader.present();
      if(msg.payload != undefined && msg.payload != null){
        let payload : any = msg.payload;
        if(payload.id != ""){

              this.paymentService.getPayments(payload.id).then((result : Response) => {
                if(result.success){
                  if(result.eror!= null && result.eror == "id invalido"){
                    this.session.clearSession();
                    this.nav.setRoot(Login);
                  }
                  else{
                    if(result.data!= null && result.data.expensas.length > 0){
                        this.payment = result.data.expensas[0];
                        this.payment.date = this.payment.diahabil;
                        if(this.payment.diahabil > this.payment.date1 && this.payment.date2.toString() != "0000-00-00")
                          this.payment.suggested = this.payment.importe2;
                        else
                          this.payment.suggested = this.payment.importe1;
                        this.accountService.getAccounts().then((result : Response) => {
                          if(result.success){
                            if(result.data.accounts != null && result.data.accounts.length > 0){
                              loader.dismiss();
                              this.payment.account = result.data.accounts[0];
                              this.nav.setRoot(OneClickPayment, {
                                item : this.payment
                              });
                            }
                            else{
                              loader.dismiss();
                              this.payment.account = result.data.accounts[0];
                              this.nav.setRoot(PaymentInformation, {
                                item : this.payment
                              });
                            }
                          }
                        });
                    }
                  }
                }
              });
        }
      }
      loader.dismiss();
      this.nav.setRoot(NextPayments);
        });
  }

  readPushNotification(){
      this.push.register().then((t: PushToken) => {
        return this.push.saveToken(t);
      }).then((t: PushToken) => {
        this.session.setPnToken(t.token);
      });
  }

  registerBackButtonAction() {
    this.platform.registerBackButtonAction(() => {
      let activePortal = this.ionicApp._modalPortal.getActive();
      if (activePortal) {
        activePortal.dismiss().catch(() => {});
    activePortal.onDidDismiss(() => {});
    return;
  }
  if(this.menuCtrl.isOpen()){
    this.menuCtrl.close();
  }
  else{
    let view = this.nav.getActive();
    if(view.component.name == "NextPayments" || view.component.name == "Login")
      this.showExit();
    else
          return view._nav.canGoBack() ? view._nav.pop() :         this.goBacktoDefaultPage();
        }
    }, 1);
  }

    goBacktoDefaultPage(){
      if(this.session.isAuth())
        this.nav.setRoot(NextPayments);
    }
   showExit() {
     if (this.backButtonPressed) {
       this.platform.exitApp();
     } else {
       this.toastCtrl.create({
         message: 'Presione nuevamente para cerrar la aplicación.',
         duration: 2000,
         position: 'top'
       }).present();
       this.backButtonPressed = true;
       setTimeout(() => this.backButtonPressed = false, 2000);
     }
   }

  initializeApp() {
      this.platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();
      Splashscreen.hide();
      this.registerBackButtonAction();
      this.readPushNotification();
    });
    if(navigator['connection']['type'] == "none"){
        let alert = this.alertCtrl.create({
          subTitle: "No posee conexion a internet. La aplicación se cerrara. Por favor reintente cuando posea conectividad.",
      buttons: [
        {
        text: 'Aceptar',
        handler: () => {
          this.platform.exitApp();
        }
      }
      ]
    });
        alert.present();
    }
  }

  openPage(page : any) {
    // Reset the content nav to have just this page
    // we wouldn't want the back button to show in this scenario
    this.nav.setRoot(page.component);
  }

  logout(){
    this.session.clearSession();
    this.userService.setToken(null);
    //UNREGISTER PUSH NOTIFICATION TOKEN
    this.push.unregister();

    this.nav.setRoot(Login);
  }
}

Any suggestion? do you need more information? It's my first app in Ionic2 and taking 15 seconds to load is not acceptable. Please help to find a solution, I invest a lot of time in this app.


EDIT: package.json updated:

"@angular/animations": "^4.0.0",
"@angular/common": "4.0.0",
"@angular/compiler": "4.0.0",
"@angular/compiler-cli": "4.0.0",
"@angular/core": "4.0.0",
"@angular/forms": "4.0.0",
"@angular/http": "4.0.0",
"@angular/platform-browser": "4.0.0",
"@angular/platform-browser-dynamic": "4.0.0",
"@angular/platform-server": "4.0.0",
"@ionic-native/core": "3.4.2",
"@ionic-native/push": "^3.4.4",
"@ionic-native/splash-screen": "3.4.2",
"@ionic-native/status-bar": "3.4.2",
"@ionic/cloud-angular": "^0.12.0",
"@ionic/storage": "2.0.1",
"@ngtools/webpack": "1.3.0",
"angularfire2": "^2.0.0-beta.8",
"firebase": "3.7.8",
"ionic-angular": "3.0.1",
"ionicons": "3.0.0",
"rxjs": "5.1.1",
"sw-toolbox": "3.4.0",
"zone.js": "^0.8.4"

回答1:


Try crosswalk or crosswalk lite and see how the performance is.The APK size will increase by 15-30 MB depending on the crosswalk you're using,but you can expect a uniform performance throughout different devices.




回答2:


Try to update your app... 2.0.0-rc.4 use a really out of date version of Ionic and Angular.

You can find more info here: changelog Ionic2

I'm working on a big app with a lot of plugins and images, and with ionic run android --prod, app is taking like 3-4 seconds to start in a real device (Galaxy S4 - relatively old).

Is a tedious job, but sooner or later you will have to do it... A lot of new features have been added too!

That's my package.json, to give you an idea:

  "dependencies": {
    "@angular/animations": "4.0.1",
    "@angular/common": "4.0.1",
    "@angular/compiler": "4.0.1",
    "@angular/compiler-cli": "4.0.1",
    "@angular/core": "4.0.1",
    "@angular/forms": "4.0.1",
    "@angular/http": "4.0.1",
    "@angular/platform-browser": "4.0.1",
    "@angular/platform-browser-dynamic": "4.0.1",
    "@ionic-native/barcode-scanner": "3.4.4",
    "@ionic-native/camera": "3.4.4",
    "@ionic-native/core": "3.4.4",
    "@ionic-native/facebook": "3.4.4",
    "@ionic-native/google-plus": "3.4.4",
    "@ionic-native/network": "3.4.4",
    "@ionic-native/social-sharing": "3.4.4",
    "@ionic-native/splash-screen": "3.4.4",
    "@ionic-native/sqlite": "3.4.4",
    "@ionic-native/status-bar": "3.4.4",
    "ionic-angular": "3.0.0",
    "ionicons": "3.0.0",
    "jsbarcode": "3.5.9",
    "moment": "2.18.1",
    "rxjs": "5.3.0",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.5"
  },
  "devDependencies": {
    "@ionic/app-scripts": "1.3.0",
    "typescript": "2.2.2"
  }

Best solution maybe will be starting a new project and add your plugin/src code. With Ionic 2 v3.0.1 (2017-04-06) app starts is really fast in production mode.

I hope to have been a help to you. :)




回答3:


use lazy loading of pages instead of declaring all pages in the app.module.ts. In app.component.ts declare the root page as string instead of any rootPage: String = HomePage. Also while declaring the pages for navigation just declare as this.navigation.push("secondPage"). we don't need to import the page for navigation purposes..




回答4:


Check to see if Firebase is causing the slow loading. Some users (myself included) are currently experiencing a similar issue. Here is a discussion with some tips: https://forum.ionicframework.com/t/ionic-3-super-slow-with-firebase-on-device-emulator/87233/50




回答5:


consider minifying your code using js minifier of your choice, I prefer uglify and use it via gulp task runner

first install gulp-cli via npm globally, and then install gulp in the dev folder and then all needed gulp plugins(gulp-useref, gulp-uglify, gulp-if), then in the index.html file surround all js references by comments that will be used by useref to combine all js files in one file and replace their references by one reference

<!--build:js build/all.js -->

<script src="build/vendor.js"></script>
<script src="build/main.js"></script>

<!-- endbuild -->

then create a gulpfile.js in the development folder

var gulp = require("gulp");
var uglify = require("gulp-uglify");
var useref = require("gulp-useref");
var gulpIf = require("gulp-if");


gulp.task('build', function () {

    gulp.src('www/index.html')
        .pipe(useref())
        .pipe(gulpIf('*.js', uglify()))
        .pipe(gulp.dest('www'));

});

then open cmd in the dev folder and run gulp build the js files will be combined and minified and the reference in the index.html will be updated accordingly

you can also use use del plugin to delete unnecessary files

Edit

passing the --prod flag to the build command makes use of Ahead-of-Time compilation that uglifies the js files prior to building the package



来源:https://stackoverflow.com/questions/43383035/ionic2-performance-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!