App boot time: current state and best practices

Hi guyz,

There are many posts on the the forum regarding Ionic2 and the current subjects “App boot time too slow” or “Speed up boot load time” or “splash screen take too much time” or “taking too much time to load” so I was thinking that I could open a post about the current state and with some current best practices/possibilities.

If you let comments here under with some good inputs, I gonna try to follow and edit the following list.

Current state:

  • Ionic2 app boot time on real devices is currently dependent of the size of your javascript bundle. Bigger your main.js gonna be, slower your startup gonna be, because everything is loaded when you start your app.

  • The Ionic team is aware of these facts and they are working, as far as I know, on two solutions

  1. On the build side, they try to introduce algorithms wich should shrink the size of the build

  2. For a longer run, for the future, they think and work on the possibility to lazy load the pages (“only loading one or a couple of pages on startup will reduce the start time because not everything will have to be loaded”)

Current best practices:

  • When you build your app, at least for a real device, always use “–prod” in your cmd line (like “ionic build ios --prod”)

  • If you build your app for production release on android, use “–prod” and “–release”. Summarized “–prod” tell the build it should be compressed, “–release” tell cordova the app should be signed (“ionic build android --prod --release”)

  • Try to shrink your app size. For example if you could:

  1. Analyze your pages and providers, save code lines. If you see not used codes, delete it. Refactor your codes to find codes you could merge. Like having two methods or pages which are quite the same and having just one at the end which you could be variable with parameters.

  2. If you ship your fonts with your app, if you notice that some aren’t used, delete them (I was shipping italic fonts with my app but they weren’t used)

  3. Have a look the external libraries you used. Try to find the big ones and if possible, try to replace them with smaller one. And of course if not used, delete them. To analyze your main.js you could use source-map-explorer (once installed, in www/build, run source-map-explorer main.js main.js.map)

I have no pretension but thought that we could summarize some best practices.

Small is beautiful.

P.S.: Plz don’t post here under thought about what should Ionic team do or don’t. My understanding is that they are full aware of the situation and working hard on it. My goal with that post, is to let us find some best practices we could use to achieve the best we could now.

18 Likes

1.use rollup. It shaves between 7 and 10 % off of your package size compared to default

ionic build android --rollup --prod --release

or

npm run build --rollup --prod

2.use ionic-native 3.x

3.This is not a speed-up trick but still maybe someone will find some use for it. App’s index.html is usually loaded pretty fast, so you can animate user within index.html while the app component is really loading in the background. When the app is loaded it replaces your loader.

<!-- Ionic's root component and where the app will load -->
<ion-app>
    <style>
        .loader {
            font-family: "Droid, Roboto, Helvetica, Tahoma";
            font-size: 1.4em;
            position: absolute;
            top: 50%;
            left: 50%;
            margin-top: 0px;
            margin-left: -40px;
        }
    </style>
    <div class="loader">Fake like app is doing something really important</div>
</ion-app>
2 Likes

Update to the current status: Lazy loading is, if I understood correctly, coming for beta testing soon

2 Likes

Update: Ionic 3 Beta introduce lazy loading, see

https://forum.ionicframework.com/t/ionic-3-0-0-beta/?source_topic_id=80690
1 Like

I’ve been trying to improve my startup for the past couple of days. So, I’d like to share my tips and experience.

===================================================================================
White screen after splash screen going hidden

Always seen this problem faced by newcomer.

Avoid using autohide splash screen altogether

/*
config.xml
 */

<preference name="AutoHideSplashScreen" value="false"/>
<preference name="FadeSplashScreen" value="false"/>

Instead, manually control the hiding from within your code

/*
app.component.ts
 */

// use SplashScreen Plugin
import {Splashscreen} from 'ionic-native'

@Component({
    templateUrl: '../pages/app.html'
})
export class MyApp {

	constructor(
    ) {

		platform.ready().then(() => {

			// platform ready, should take somewhere below 5s

			// don't hide the splash screen right here, otherwise, you'll see a white screen

			// you'll be doing lots of operation here
			
			// when everything is done, now you can hide the splash screen			

			// even so, the operation here can take another 2 to 3 seconds			

			Splashscreen.hide();

		}

    }  
}

===================================================================================
Don’t setup everything everytime, keep things that need to be run on installation
and the one on every launch separate. I manage to shave 2s off from this method.

As mentioned, there’s some operation before your app is ready which can take 2-3 seconds, or more. This include things like directory setup, local database table creation, push setup, etc. First thing you need to do is profiling to find the bottleneck. You can user javascript own ‘performance’ for this. On production built, you can use online https://jsconsole.com/ to log out the info.

eg:

platform.ready().then(() => {

	let t1 = performance.now()
	// setup directories
	console.log(`Setting up directories took ${performance.now() - t1} ms`)

	let t2 = performance.now()
	// setup database tables
	console.log(`Setting up directories took ${performance.now() - t2} ms`)

	Splashscreen.hide();

}

Use Storage plugin to identify the launch condition (either first installation or subsequent launch)
Only run if its on the first time installation

platform.ready().then(() => {

	this.storage.get('installed').then(
		(result:any)=>{
			// not yet installed, lets set things up
			if(!result){
				let t1 = performance.now()
				// setup directories
				console.log(`Setting up directories took ${performance.now() - t1} ms`)

				let t2 = performance.now()
				// setup database tables
				console.log(`Setting up directories took ${performance.now() - t2} ms`)
			}
			
		}
	)

	this.storage.set('installed', 1)
	Splashscreen.hide();
}
3 Likes

cool thx for the contribution, interesting!

Update: Ionic 3.0.1 is out.

With the use of Ionic Native > 3 the boot time gonna be a little faster, since only the needed plugins gonna be included in the build and not all of them.

Furthermore, Ionic 3 is shipped with Angular 4 which should be also a little bit faster.

When it comes to lazy loading, if I understand correctly, it’s not yet production ready, specially if you, like I do, have mutliple components to include multiple times in your project.

I have an error with --rollup:

ionic build android --rollup --prod

    > project@ ionic:build /Users/user/Documents/project-folder
    > ionic-app-scripts build "--rollup" "--prod"

    [09:44:32]  ionic-app-scripts 1.3.2 
    [09:44:32]  build prod started ... 
    [09:44:32]  clean started ... 
    [09:44:32]  clean finished in 5 ms 
    [09:44:32]  copy started ... 
    [09:44:32]  ngc started ... 
    [09:44:41]  ngc finished in 9.14 s 
    [09:44:41]  preprocess started ... 
    [09:44:41]  deeplinks started ... 
    [09:44:41]  deeplinks finished in 7 ms 
    [09:44:41]  optimization started ... 
    [09:44:42]  copy finished in 9.29 s 
    [09:44:54]  optimization finished in 12.87 s 
    Config file "/Users/ftavallini/Documents/project-folder/--prod" not found. Using defaults instead.
    [09:44:54]  preprocess finished in 12.87 s 
    [09:44:54]  rollup started ... 
    [09:44:58]  ionic-app-script task: "build" 
    [09:44:58]  Error: Unexpected token 
    Error: Unexpected token
        at error (/Users/ftavallini/Documents/project-folder/node_modules/rollup/dist/rollup.js:170:12)
        at Module.error$1 [as error] (/Users/ftavallini/Documents/project-folder/node_modules/rollup/dist/rollup.js:7997:2)
        at tryParse (/Users/ftavallini/Documents/project-folder/node_modules/rollup/dist/rollup.js:7700:10)
        at new Module (/Users/ftavallini/Documents/project-folder/node_modules/rollup/dist/rollup.js:7735:14)
        at /Users/ftavallini/Documents/project-folder/node_modules/rollup/dist/rollup.js:9481:17

Do you know any solution please?

@alfabetagama about your idea “animate user within index.html”, I find this pretty cool.

Do you see any risks doing that? Furthermore, if I understand correctly, you don’t use/removed the cordova-plugin-splashscreen from your project right?

I tried it, on the browser (ionic serve) works fine but it doesn’t works when I test it on my iPhone (no loading text is displayed). Are you more successful?

btw. when I tried your code, the styling wasn’t loaded. It turns out I add to put the style in the app.component.scss to make the styling happens

1 Like

IOS requires splashscreen AFAIK. I am compiling separately for Android because of boot time issues so i removed splash screen completely for this purpose.

In your package.json

"scripts": {
    "build": "ionic-app-scripts build --rollup",
 ....

then you can run ionic build android --prod or call npm run build

you can also create platform specific scripts by copying and customizing configurations from node_modules/@ionic/app-scripts/config, for example to remove all non material design CSS or some unneeded fonts from final package:

"scripts": {
    "build-android": "ionic-app-scripts build --rollup ./config/rollup.config.js --experimentalManualTreeshaking true --experimentalPurgeDecorators true --sass ./config/sass.config.md.js --useExperimentalClosure true --closure ./config/closure.config.js",

then run
npm run build-android --prod

and

cordova build android --release

to create android release package

1 Like

@alfabetagama thx for your answer, that would explain why I could achieve it on iOS :wink: May not be a solution for me then, as much as possible, want to stick to the same solution for both iOS and Androi

According to this: https://docs.google.com/document/d/1vGokwMXPQItZmTHZQbTO4qwj_SQymFhRS_nJmiH0K3w/edit it is possible to use lazy loading.

There is this question too: http://stackoverflow.com/questions/43339695/ionic-3-refer-a-new-page-in-app-module-issue

@brunosmartin yes you’re right, it’s possible to do lazy loading with Ionic 3.

But is, in my point of view, not yet mature. The major reason behind that is that code, of components, may most probably duplicated in your different bundles.

For example see: https://github.com/driftyco/ionic-app-scripts/issues/867

About lazy loading, Mike from Ionic published a first article yesterday:

http://blog.ionic.io/ionic-and-lazy-loading-pt-1/

If you app is only accessible via a login, there is an interesting post with some ideas about how to design the root pages and services. It allowed me to save some ms:

About lazy loading, I don’t use it right now because including the components result in my project of many duplication of their codes in the bundles.

But there is hope, therefore I just list here some issue/pull request I found related to this subject:

Webpack issue: https://github.com/webpack/webpack/issues/3981

Webpack related PR: https://github.com/webpack/webpack/pull/4416 and https://github.com/webpack/webpack/pull/4255

Angule CLI issue: https://github.com/angular/angular-cli/issues/6204 and https://github.com/angular/angular-cli/issues/2771

Ionic app-script issue: https://github.com/driftyco/ionic-app-scripts/issues/867

Hello @alfabetagama, We used ionic v2.2.0 and typescript v1.0.0 and made 14-15 features in my app and also used 8-10 ionic plugins which is used in application. My app takes 20-22 sec to load app in android and ios device. so, my question is why it takes that much time? Do you know about Lazyloading or any preloading technique so we can reduce app load time… we used ionic build android --prod --release command to generate .apk file. Please help me… thank you

Hello @reedrichards, We used ionic v2.2.0 and typescript v1.0.0 and made 14-15 features in my app and also used 8-10 ionic plugins which is used in application. My app takes 20-22 sec to load app in android and ios device. so, my question is why it takes that much time? Do you know about Lazyloading or any preloading technique so we can reduce app load time… we used ionic build android --prod --release command to generate .apk file Please help me… thank you

Hi @Dhyanandra your question is way to open :wink:

Plz open a separate post and document it with logs output and other (more) informations otherwise it will be hard for the community to help you