ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
50.58k stars 13.52k forks source link

Speed up initial loading #6776

Closed TheMohanraj closed 7 years ago

TheMohanraj commented 8 years ago

We're developing an app which is partially native and partially hybrid. We will open cordova activity when user clicks on an menu item and finish the activity when user clicks back. Problem with this approach is, it takes a while to render on the screen for first time. We are hosting all the resource files in the assets folder so caching doesn't make much sense. Is there any progressive way to load the application?

zerocode000 commented 7 years ago

with regards to @prijindal 's approach of putting the templates into the Component, will this be the same optimization level expected from the offline compilation? I tried this approach, it saves the time of the HTTP requests to fetch the template, but there is still a lag at first view load. I suppose this happens because angular compiles the custom html of the templates at the first view load.

I am quite new to angular and I would appreciate if someone can clarify this to me.

danbucholtz commented 7 years ago

@moatazelgamal,

AoT compiling will result in a significant speed-up. It takes several seconds to run the compiler for a typical app ahead-of-time, so this is time shaved off from runtime. It's hard to say how much faster it will be for a typical app. We've only tested it on a very basic sample and the start-up time went from ~3 seconds to ~300ms. We have not done enough testing to know what sort of numbers a typical app will see, but it will most certainly be faster.

The changes for AoT are in place for the framework (we think... so far so good 😄 ) and now we're shifting over to making the build process A) simple, B) scalable and C) as fast as possible. The team and I are working on it together in this repo.

Expect to hear more soon.

Thanks, Dan

prijindal commented 7 years ago

@moatazelgamal my approach is not offline compilation, it is simply inlining templates. Offline compilation is going to make the initial loading a lot faster.

danbucholtz commented 7 years ago

All,

We are heavily testing this internally now. We've made some great strides this week.

Thanks, Dan

zerocode000 commented 7 years ago

Hello there, I see Ionic2 RC0 was released, Is this the expected beta12? The changelog of RC0 did not mention anything about AOT compiling. I think this feature is too good to be missed in the changelog :)

danbucholtz commented 7 years ago

It was "released". We're still filling in the gaps right now 😄 with changelog, etc. Expect official details later today. We ran into technical difficulties yesterday so we're a little bit behind.

Thanks, Dan

gisinaction commented 7 years ago

Hi Ionic Team! Thanks for your hard work!

masimplo commented 7 years ago

So excited about this. Can't stop tweeting since I first read about it. Kudos ionic team.

On Thu, Sep 29, 2016, 04:19 gisinaction notifications@github.com wrote:

Hi Ionic Team! Thanks for your hard work!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/driftyco/ionic/issues/6776#issuecomment-250346182, or mute the thread https://github.com/notifications/unsubscribe-auth/AAxEjznTYrcKZKFD2rElIqKkWrGIvvUrks5quxIvgaJpZM4Iuokt .

SynerG commented 7 years ago

First of all, thank you for this great progress! I have been testing the new version and the initial loading now feels faster.

I have also been testing it in a low-spec Android 4.4.4 to better feel the performance difference and comparing it to Ionic 1. With Ionic 2-rc0, I find these approximate results:

Project Cold boot Hot boot
ionic1-tabs 4,5 s 3 s
ionic2-tabs 5 s 3,5 s
ionic1-sidemenu 5 s 3,5 s
ionic2-sidemenu 5 s 3,5 s
clock (native app) 1 s <1 s
ionic start myTabs1 tabs
ionic start myTabs2 tabs --v2
ionic start mySidemenu1 sidemenu
ionic start mySidemenu2 sidemenu --v2

Although the projects are not the exact same implementations, they give us a starting point for comparison.

Even with ionic 2-rc0, the basic projects require around 5 secs to load up on cold, and around 3,5 secs when it had already been loaded previously. These are roughly the same times that I find with Ionic 1 versions. The blog post that introduces Ionic2 RC0 contains an animated gif showing the current load up time. Around 3 seconds.

Do we know where are the remaining seconds spent? (eg. Starting up the Javascript engine/webview, Cordova plugins, Angular 2 loading, ...)?

Can these seconds be optimized to have an experience closer to native apps?

danbucholtz commented 7 years ago

@SynerG, great info. I am a little swamped with some other stuff right now but we will have more feedback soon. Thanks for putting that together!

Thanks, Dan

ghost commented 7 years ago

i created a new ionic2 rc-0 project with side menu. I used ionic serve --lab, and when i click the icon at the left side of header bar, the menu doesn't not come out. only when i slide or click the menu toogle button that it slides

abhayastudios commented 7 years ago

@danbucholtz I wanted to thank the Ionic team for releasing RC0! Even though I had to invest some time to migrate my app due to all the changes, the startup time of my app improved significantly! For example, on a 3 year old Samsung Galaxy 4 the startup time with beta 11 was ~6 seconds which RC0 reduced to ~3 seconds! It's a great improvement so well done :)

danbucholtz commented 7 years ago

@abhayastudios, w00t! Thanks!

We have more improvements and optimizations in store, too!

Thanks, Dan

daveshirman commented 7 years ago

We too have had our load time slash by about 50%. Great work guys. Really loving working with this framework.

geocine commented 7 years ago

I know this doesn't help but I just recently dived into ionic and I am using 2.0.0-rc.2 , I noticed how slow the initial load was compared to an app that was built on 1.1.1

Kobzol commented 7 years ago

@geocine I noticed the same thing, in an older v1 app, the startup time is very good but while Ionic v2 provides a much nicer programming environment, the startup times are very slow in my app (>5 seconds in release build on a relatively fast device with Android 6.0). Is the Webpack build doing tree shaking?

geocine commented 7 years ago

If it really takes time to load , perhaps is there a way to atleast show a splashscreen that I can show in under a second during loading?

lordgreg commented 7 years ago

@geocine That's why you usually use the cordova splash screen plugin (https://github.com/apache/cordova-plugin-splashscreen) and hide it onDeviceReady.

Kobzol commented 7 years ago

Is there any easy way to profile the app startup time? I'm using Chrome remote debugger to profile the app, however that lets me connect to the app only after it's already initialized (so I cannot profile the startup) and it closes when I exit the app, so I cannot relaunch it and profile the startup this way.

I'm asking this because I'm having problems with my app startup time on Android, which is above 5 seconds. Even when I use the plain Ionic 2 tutorial app, it starts only after 4-5 seconds on a relatively performant device (Sony Z3 compact, 6.0.1). That's really slow (my old Ionic 1 app with a few plugins takes < 3 seconds to start).

Are there any plans to (significantly) reduce Ionic 2 app startup times? Developing with Ionic 2 is great, but I'm afraid that otherwise I'll have to switch to another framework :-(

naveedahmed1 commented 7 years ago

Are there any plans to add support for Lazy loading, this could also be helpful in reducing initial load time. Angular cli which uses webpack now supports Lazy loading and with AoT a well designed angular app can significantly reduced load time. Since Ionic also uses webpack, I think this can be done for Ionic as well.

bugbuka commented 7 years ago

urgent needs for Lazy loading.

msaelices commented 7 years ago

The ionic team meeting doc said that they are working in treeshaking, so probably this will reduce the bundle size and will speed up a little the boot up time.

rob3c commented 7 years ago

Tree shaking is great, but it can only do so much. Lazy loading is an important separate concern, and so far, the ionic team hasn't expressed much interest in it according to comments I've seen in other issues (e.g. https://github.com/driftyco/ionic/issues/8102). Unfortunately, many people seem to think it's only useful in web apps, even though it can also be incredibly useful in mobile apps too.

danbucholtz commented 7 years ago

@rob3c and others,

Lazy loading is something we're looking at and would like to explore more. Expect to hear more on this topic in the coming months.

Thanks, Dan

SynerG commented 7 years ago

@danbucholtz, Beyond lazy loading, are you exploring any other solutions that could significantly reduce the start up time?

Right now, this is the number 1 reason we are not adopting Ionic 2 in new projects. I don't know if you could share with us some information about what is in process. Thanks!

masimplo commented 7 years ago

Well this is a problem with javascript in general and not specific to ionic. It is interesting to see what other frameworks are doing about it. For example I stumbled upon a related article on a "competive" framework's website using what is called "code caching" in the v8 engine to vastly improve startup performance.

Kobzol commented 7 years ago

The startup time has gotten a lot worse after Angular 2 switched to modules due to AoT. In NativeScript, which also has problems with long startup time, it seems that it's fine without Angular 2 (https://github.com/NativeScript/nativescript-cli/issues/371). In june my app was starting relatively fast, but after Ionic 2 switched to newer version of Angular 2, it now takes >= 5 seconds and that is unusable for production. Are you aware of any Angular 2 improvements that are in the making to improve this or is treeshaking and lazy loading the only way?

danbucholtz commented 7 years ago

@Kobzol,

That is strange, AoT definitely results in a significantly faster start-up time (typically, anyway, I am sure there are edge cases).

@SynerG,

Start-up time is pretty fast with AoT. You sure you were testing with AoT? Our bundle size is still relatively large and we are working on bringing that down. It isn't completely huge though unless you import a bunch of large libraries. Often times small libs become huge due to a bunch of nested dependencies.

Thanks, Dan

Kobzol commented 7 years ago

I don't know if I'm doing anything wrong, but I tried to run AOT prod builds of the Ionic 2 tutorial starter template with both webpack and rollup and it takes > 5 seconds to start on my device (Sony Z3 Compact with Android 6.0.1), whereas an older Ionic 1 app starts in 3 seconds. The startup got worse over the last couple of months, when Angular 2 switched to the module system (the same happened with my nativescript app, which slowed after the Angular switch). Maybe lazy loading could help with that.

Do you have any benchmark numbers that I could use for comparison?

biesbjerg commented 7 years ago

5 seconds is not that bad compared to what I've been seeing. I've had to up the timeout limit in config.xml to make sure it does not timeout (default is 20 seconds!).

That was for a slower 4.4 device though. On a Sony Xperia E5 with 6.0 it is still 10-15 seconds.

iPhone 7 plus is less than 2 seconds.

danbucholtz commented 7 years ago

How big are your bundles? Are you using lots of third party libraries?

Thanks, Dan

biesbjerg commented 7 years ago

Hi Dan!

Nothing too crazy I think.

My bundle size using webpack and AoT is 1.9MB.

Deps in package.json

...
  "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",
    "@biesbjerg/ng2-translate-po-loader": "^0.1.3",
    "@ionic/app-scripts": "0.0.46",
    "@ionic/storage": "1.1.6",
    "@ngrx/core": "1.2.0",
    "@ngrx/effects": "2.0.0",
    "@ngrx/store": "2.2.1",
    "angular2-uuid": "1.1.0",
    "ionic-angular": "nightly",
    "ionic-native": "2.2.7",
    "ionicons": "3.0.0",
    "ng2-translate": "^4.1.0",
    "ngrx-store-freeze": "0.1.4",
    "ngrx-store-logger": "0.1.7",
    "pofile": "^1.0.2",
    "rxjs": "5.0.0-beta.12",
    "zone.js": "0.6.26"
  },
  "devDependencies": {
    "@biesbjerg/ng2-translate-extract": "^0.1.1",
    "@ionic/app-scripts": "0.0.46",
    "@types/cordova-plugin-media": "0.0.3",
    "del": "^2.2.2",
    "fs": "0.0.1-security",
    "path": "^0.12.7",
    "typescript": "2.0.10"
  },
  "cordovaPlugins": [
    "cordova-plugin-device",
    "cordova-plugin-console",
    "cordova-plugin-whitelist",
    "cordova-plugin-splashscreen",
    "cordova-plugin-statusbar",
    "ionic-plugin-keyboard",
    "cordova-plugin-globalization",
    "cordova-plugin-media",
    "cordova-plugin-file",
    "cordova-plugin-compat",
    {
      "locator": "https://github.com/EddyVerbruggen/cordova-plugin-backgroundaudio",
      "id": "nl.x-services.plugins.backgroundaudio"
    },
    "cordova-plugin-app-version",
    "cordova-plugin-x-socialsharing",
    {
      "locator": "https://github.com/biesbjerg/cordova-plugin-inapppurchase.git",
      "id": "cordova-plugin-inapppurchase"
    },
    {
      "locator": "https://github.com/driftyco/cordova-plugin-wkwebview-engine.git",
      "id": "cordova-plugin-wkwebview-engine"
    },
    "cordova-plugin-google-analytics",
    "cordova-sqlite-storage"
  ],
...
graphefruit commented 7 years ago

Hello, I would like to share my own information with the startup time aswell. Actually I'm putting my old Ionic V1 to V2 (rewriting everything from scratch).

My old application with crosswalk starts up (depending on device) from 3 to 4 seconds. The new application needs 6 to 7 seconds (7 seconds are more likely).

I've tried the RC3 aswell as the nightly build (Ionic Framework Version: 2.0.0-rc.3-201612021933)

Package.json:
{
  "name": "ionic-hello-world",
  "author": "Ionic Framework",
  "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/storage": "1.1.6",
    "ionic-angular": "^2.0.0-rc.3-201612021933",
    "ionic-native": "2.2.3",
    "ionicons": "3.0.0",
    "moment": "2.15.1",
    "rxjs": "5.0.0-beta.12",
    "zone.js": "0.6.26"
  },
  "devDependencies": {
    "@ionic/app-scripts": "0.0.44",
    "typescript": "2.0.9",
    "webpack-bundle-analyzer": "^1.5.3"
  },
  "cordovaPlugins": [
    "cordova-plugin-whitelist",
    "cordova-plugin-statusbar",
    "cordova-plugin-console",
    "cordova-plugin-device",
    "cordova-plugin-splashscreen",
    "ionic-plugin-keyboard"
  ],
  "cordovaPlatforms": [],
  "description": "o2: An Ionic project"
}

My assets folder (third party plugins / images) is about 2.14 MB. I'm using 6 different third-party plugins (jQuery, moment, hammer, jquery 3.1, fullcalendar, svg-panzoom, fontawesome).

The APK-Size is: 6.58 MB Unzipped this package is: 15 MB.

Folding:

Ionic-Version information:

Your system information:
Cordova CLI: 6.4.0
Ionic Framework Version: 2.0.0-rc.3-201612021933
Ionic CLI Version: 2.1.13
Ionic App Lib Version: 2.1.7
Ionic App Scripts Version: 0.0.44
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 8.1
Node Version: v6.9.1
Xcode version: Not installed

Maybe it helps, if you @danbucholtz / @jgw96 could use my actual project to debug this problem I'd be happy to share it (private).

Greetings Graphefruit

naveedahmed1 commented 7 years ago

I believe sourcemaps should be disabled for production build. Angular CLi recently added an option to disable it https://github.com/angular/angular-cli/pull/3262

Graphefruit can you please also share the number of components and directive your app have?

graphefruit commented 7 years ago

Hello @naveedahmed1, here we go:

Greetings Graphefruit

rob3c commented 7 years ago

@naveedahmed1 That issue is about not inlining sourcemaps, which I agree probably isn't the best idea in production. However, external map files for production assets can be useful and only add a small comment to the deployed files. I'd definitely like to be able to generate external map files for production builds.

danbucholtz commented 7 years ago

@rob3c,

It will be configurable.

Thanks, Dan

savanvadalia commented 7 years ago

@danbucholtz, we really need improvement on the boot time. Even the ionic-conference-app downloaded from play store takes 9-10 seconds on my Samsung Galaxy S4 Android Version 5.0.1. This is the app I downloaded --- https://play.google.com/store/apps/details?id=io.ionic.conferenceapp

Boot time for my app with few pages is about 7-8 seconds on the same phone.

graphefruit commented 7 years ago

So I've tried to attach me via Developer-Tools and got a pretty good timeline-result. I couldn't track from start because attaching, but you see whats happening: image

The Compile Script takes about 500ms, the evalute script from 0ms to 5000ms.

If needed @danbucholtz @jgw96 I can send you the saved timeline for this.

Kobzol commented 7 years ago

How did you manage to profile this? I can't connect to the app until it's fully started.

BTW I don't know if that's a good result for you, but sadly for my client > 5/6 second startup time is unacceptable.

graphefruit commented 7 years ago

@Kobzol it isn't a good result, page needs 7s ~ aswell. What I did: Open a page, see your attached device list, start the app first time normal, open the "inspector" switch to timeline tab Close the app now, and the inspector, now start the app again, press inspect, press the in the timeline tab ultra fast the record button ;) The first 1-2 seconds when the app is starting I cant attach aswell, but the rest is possible with a bit of speedy fingers.

Update: With Ionic1 I got a startuptime 3-4 seconds which was quite acceptable for me

danbucholtz commented 7 years ago

Are you building with AoT? Those times seem slow.

Thanks, Dan

savanvadalia commented 7 years ago

@danbucholtz, In my case I downloaded ionic-conference-app from the play store, pretty sure it would be AOT compiled, please see my comments here

danbucholtz commented 7 years ago

@savanvadalia,

We pulled it out of the play store because it actually wasn't AoT bundled. Our developer made a mistake before publishing. We'll republish a new version soon.

Can you install the latest version of the ionic CLI and app-scripts?

npm install -g ionic@latest
npm install @ionic/app-scripts@latest

And then run ionic build android --prod --release? This will give you an AoT build with an optimized APK. It should start much faster than 9 seconds even on a slow device.

Thanks, Dan

Kobzol commented 7 years ago

@Dan on what devices are you testing this? Even with every package updated, I can't get under 6 seconds and from what I've seen here, others are having similar experiences.

graphefruit commented 7 years ago

Did anyone managed to install the latest app-scripts?

Update problems:

If I try to install the latest app-scripts I get following error: (I installed ionic@latest before)

C:\Users\graphefruit\Documents\o3>npm install @ionic/app-scripts@latest
ionic-hello-world@ C:\Users\graphefruit\Documents\o3
`-- @ionic/app-scripts@0.0.47  invalid
  +-- rollup@0.36.4
  +-- rollup-plugin-commonjs@5.0.5
  `-- xml2js@0.4.17
    +-- sax@1.2.1
    `-- xmlbuilder@4.2.1

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\ch
okidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@
1.0.15: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"
})

After this I started a complete new project, ionic start o4 --v2 with the same error.

Maybe I don't get the update mechanismen - do I need to grab myself into the package.json, or need to delete the node_modules folder? I tried to update manually set app-scripts, and run npm install, but it crashed. Neither the package.json was updated automatic to 0.47

So I build the project now with 0.0.45 and --prod --release

And the startup time was 7-8s aswell.

savanvadalia commented 7 years ago

@danbucholtz I think I have always been using AOT until now as I remember I saw ngfactory files somewhere. I am still bit resistive at present to move to newer app-script version as my current version 0.0.46 was doing a decent job for me. But anyways I will take your word and update to 0.0.47 and let you know what happens.

Savan

savanvadalia commented 7 years ago

@danbucholtz I updated to latest ionic-app-scripts and started receiving this error (See below screenshot). Also I have strictly followed the upgrade procedure mentioned in the release notes.

Could you please help with this?

image

Thanks Savan

savanvadalia commented 7 years ago

@graphefruit I didn't had any issues with installing latest ionic-cli and installing npm packages at project level. I hope you are following the release procedure here. But, as I mentioned above I am getting a different run-time error "Unexpected value 'undefined' declared by the module 'AppModule'".

Also running 0.0.45 with --prod --release won't help. Dan asked to run that with version 0.0.47 as from 0.0.47 and on wards this will be the way to generate a production build. With prior ionic-app-script versions ionic run android generated the production build by default.

graphefruit commented 7 years ago

@savanvadalia Thanks for your feedback, in the procedure theres not much written. I also started a fresh project, and did npm install -g ionic@latest before. So you just runned both commands in your project folder? Or did you do any specific? Like I said, I already tried to remove the node_modules folder aswell, and did npm-install afterwards. But in my opinion, it won't help when the package.json isn't updated to the latest app-scripts version. 0.47 but when I do this manually it crashes even more...

Normaly they post in the changelog the newest package.json and what to update.

Update, finally managed it to resolve it with these commands:

npm install ionic-angular@nightly --save
npm install @ionic/app-scripts@latest --save-dev

Let the build begin.

Build test

So, build went through, funny fact - I needed to "strg +c" because ngc-started was shown for more then 10 minutes, after this, the build was continued, the second time it run without any problems.

Size: 9.2 MB The main.js.map is still existing when building for production

Starting the app needs 7-10 seconds (depends on device) so it looks like it went more worse then before. (Note 1, Note2)

On a Google Pixel XL the startup time was about 4.5 to 5 seconds Compared to my old app-version its still 1-2 seconds slower (3.5 seconds startup time)

Your system information:

Cordova CLI: 6.4.0
Ionic Framework Version: 2.0.0-rc.3-201612142137
Ionic CLI Version: 2.1.17
Ionic App Lib Version: 2.1.7
Ionic App Scripts Version: 0.0.47
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 8.1
Node Version: v6.9.1
Xcode version: Not installed

Update 2:

I've just compared the sizes from the old build with 0.45 and with 0.47 - the main.js has (nearly ~10kb) the same size - 3MB. - Don't know if this should be affected aswell.

Update3:

Thats the best snapshot after 15 minutes try for the loading: image