[英]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-useref
, gulp-uglify
, gulp-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.