Ionic 3 Performance Boost with Observable using VirtualScroll and WKWebView

What do you do when an application you just installed is f****** slow?
——-> Straight to the garbage, no question asked.
This scenario can also happen to the applications that you develop.
Not everybody has an iPhone 7.
In today’s tuts we get this painful issue out of the way.

The objective is to go from this:

slow scroll no Ionic 3 virtual scroll

To this:

fast virtual scroll

We will go through:

  • The unoptimized case
  • The WKWebView solution
  • The Ionic 3 VirtualScroll solution
Subscribe to my mailing list to get access to a Free 7-day Ionic 3 introduction email course!
100% Privacy. I'll never spam you!

Let’s fire up our Ionic 3 app:

The same home.ts file will be used for each case:

All the work is done in the ngOnInit hook.
I haven’t found a free service that returns 1000 images on demand, so we go back to our good old lorempixel website.

First, we add 1000 image urls to a temporary array named imgArray.

Once this is done, an Observable is returned. A HTTP request now returns an Observable, that’s why we return one to simulate this case (you can have a reminder on Observables there).

Using the method of from Observable, the image array will be transformed into an Observable sequence.

Just a good old ngFor

Ionic advises us to use the <ion-img> Component, however, it has some issues with the current VirtualScroll:

So the good old <img> tag will be used to keep the tests congruency.

In the home.html:

The images are displayed inside an <ion-list>.
The ngFor Directive here creates one <ion-item> for each image we have to display.
The asyncPipe is added because we are not looping on a simple array, but on an Observable sequence.

Finally the images are displayed inside an <ion-avatar>.

The benchmark:

with 10k with wkwebview

The initial part is the Ionic 3 loading screen with a stable 10 fps.
Once the application is loaded, the fps become unstable, every time a scroll is triggered, a fps drop appears.

It’s looking very bad and that’s not how a smooth application’s benchmark should look like.
Let’s fix this ;).

Introducing WKWebView

The WKWebView API was introduced in iOS 8.
It has a better HTML5 support (added IndexedDB and ObjectStore ArrayBuffer) and has far better performances than its predecessor UIWebView.

The whole installation process is available there:

From here, 10k images will be displayed. Why? Because we can!

The results are really impressive:

with 10k with wkwebview

After the initial Ionic 3 loading (the constant 10fps).
The app is working smoothly averaging 55 fps!
All of that without modifying the source code. That’s a quick and clean fix!

The Bleeding Edge: VirtualScroll

Finally the Ionic homemade solution: the VirtualScroll.

Unlike the other cases, the VirtualScroll only renders a limited number of rows.
Even though 10K images are available:

Ionic 3 Virtual Scroll restricted number

Only a few numbers are in the DOM.
This number is just enough to give the user the impression that every images are here.

The only changes are:

The <ion-list> and the <ion-item>.
We attach the virtualScroll attribute. The displayedImages are required, alongside the asyncPipe (still using our Observable).
The virtualItem Structural Directive will do its job but requires the creation of a displayedImage variable.

And that’s it!

The performances:

fps virtual scroll

The application is running smoothly while using the good old UIWebView API.

However, this solution comes with some other issues:


We are damn lucky.
Many solutions and improvements have been created for us through the past years.
The VirtualScroll is very interesting because it allows us to virtually display thousands of images without breaking a sweat by only rendering a hundred, however, it does come with its own small issues that can be buzz killers.
On the other side, the WKWebView API is already there since iOS 8 and very stable for some great performances.
Always remember:

Speed is a requirement, not a feature

-The Ionic Team

No Comments Yet

Leave a Reply

Your email address will not be published. Required fields are marked *