繁体   English   中英

Ionic2性能问题

[英]Ionic2 performance issue

我的ionic2应用需要大约15秒钟才能在设备中启动。 我尝试了所有建议(最小化,uglify,enableProd,-prod --release等),我的最终apk为4.3MB

该应用程序没有任何图像,除非是图标和启动画面,它的屏幕少于20个,只有文本,列表和按钮(这是一个付款应用程序,所以很奇怪)

我的package.json是:

{
  "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"
}

您是否看到依赖项或插件有任何问题?

最小化的main.js文件为5.8MB。

我的app.module是:

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 {}

和我的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);
  }
}

有什么建议吗? 你需要更多的信息? 这是我在Ionic2中的第一个应用程序,加载15秒是不可接受的。 请帮助找到解决方案,我在此应用程序中投入了大量时间。


编辑:package.json更新:

"@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"

尝试使用人行横道或人行横道精简版,看看性能如何。APK大小将根据您使用的人行横道而增加15-30 MB,但您可以期望在不同设备上获得统一的性能。

尝试更新您的应用程序... 2.0.0-rc.4使用真正过时的Ionic和Angular版本。

您可以在这里找到更多信息: changelog Ionic2

我正在开发一个带有许多插件和图像的大型应用程序,并且使用ionic run android --prod ,该应用程序ionic run android --prod需要3-4秒才能在真实设备(Galaxy ionic run android --prod相对较旧)中启动。

这是一项繁琐的工作,但是迟早您将不得不这样做...还添加了许多新功能!

那是我的package.json ,给你一个想法:

  "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"
  }

最好的解决方案可能是开始一个新项目并添加您的插件/ src代码。 使用Ionic 2 v3.0.1(2017-04-06),应用程序在生产模式下启动速度非常快。

希望对您有所帮助。 :)

使用页面的延迟加载 ,而不是在app.module.ts中声明所有页面。 在app.component.ts中,将根页面声明为字符串,而不是任何rootPage: String = HomePage 同样,在声明要导航的页面时,只需声明为this.navigation.push("secondPage"). 我们无需导入页面即可进行导航。

检查Firebase是否导致加载缓慢。 一些用户(包括我自己)当前也遇到类似的问题。 这是一些技巧的讨论: https : //forum.ionicframework.com/t/ionic-3-super-slow-with-firebase-on-device-emulator/87233/50

考虑使用您选择的js缩小器来缩小代码,我更喜欢uglify并通过gulp任务运行器使用它

首先安装gulp-cli通过npm全球范围内,然后在开发文件夹中安装一饮而尽,然后将所有需要一饮而尽插件( gulp-userefgulp-uglifygulp-if ),那么index.html文件中环绕所有的JS通过评论引用useref将使用useref来将所有js文件合并到一个文件中,并用一个引用替换它们的引用

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

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

<!-- endbuild -->

然后在开发文件夹中创建一个gulpfile.js

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'));

});

然后在dev文件夹中打开cmd并运行gulp build ,将合并并缩小js文件,并相应地更新index.html中的引用

您还可以使用use del插件删除不必要的文件

编辑

--prod标志传递给build命令将利用Ahead-of-Time-time编译,该编译在构建软件包之前会丑化js文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM