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"