Delay on iOS version when clicking on router-link or ion-button?

I’ve noticed that there is a delay when you click on stuff in iOS version of the app.

My setup is @ionic/vue@5.8.4 and @ionic/vue-router@5.8.4 (latest versions as of today)

I’m a little bit familiar with this issue by reading this article.
However, based on this article, the issue should covered by Ionic but it doesn’t seem to be the case on my end.

Here is what I already tried:

  • Using standard HTML div with @click="$router.push({name: 'routeName'})

  • ion-button with @click="$router.push({name: 'routeName'})

  • Vue router-link with :to="{name: 'Dish overview'}

I’ve also tried adding tappable attribute to all of the above cases with no difference.

It works great and with no delay on Android but the delay on iOS is really annoying.

Is there anything that could be done here to improve? Should I try using fastclick.js directly?

Hard to say what the issue might be without being able to reproduce it myself. Do you have a sample app I can try?

You should not need fastclick.js anymore with the introduction of touch-action in CSS.

You’re right, it does work correctly in a starter Ionic Vue app. So it must be something else in my app that is doing this.

I’m trying to remove everything in my app one by one to see what may cause this.
In my app I use TailwindCSS (base and utilities css from it). After removing TailwindCSS completely I see improvement and the delay is very short if any at all.

However, I’ve tried adding TailwindCSS to the starter app the same way I did in my app and the delay is also very short if any at all.
The fact that I don’t see much difference with or without TailwindCSS on the starter app makes me wonder if it might be something else, maybe something related with my app size in general. But then I would expect it to be as slow on the Android side as well but it is faster than iOS version even on a slower device.

I can’t share the code as it is too big of a project at this point and I still can’t recreate the issue completely on the starter app. If I get it on the starter app, I will definitely share the code.

Any tips on how could I debug this to make sure that it is actually TailwindCSS that is causing the problem and if so, what could I do to improve the situation?

One thing to check is if the click event is being delayed or if the click event is taking a long time to complete. Your browser dev tools can help with this.

Another thing to try is to add touch-action: manipulation to the element that you are clicking and see if that helps. Browsers add a 300ms delay to click event generation when the double tap to zoom feature is enabled. touch-action: manipulation disables this double tap to zoom feature which gets rid of the 300ms delay as a result.

After a lot of investigation, I found out that the click event is not being delayed, however, after looking at the performance tab in chrome, the biggest delay comes from recalculate style. It is actually visible on Android side as well but not as much.

One solution could be to remove TailwindCSS completely but that would mean I would have to do the styling all over again.

I’ve tried using custom postcss options to purge unused styles and it is a step in a good direction, however the situation is still not ideal, also, some of the Ionic styles got messed up along the way.

This article over here has a good example of how the delay looks like: Preloading modules in Ionic v4 - DEV Community

OP fixed the issue by using a custom preload function for preloading the component. I’m trying something similar on my end with Vue but with no luck.

If you have any further tips here that I could try, that would be great. Otherwise, thanks anyway!

Do you have a sample I can run?

I wasn’t able to make a sample or share the code but after a long time and a lot of testing I figured it out. Hopefully this could be useful for future users.

I had a view with an infinite horizontal list that would load +10 items over and over again as long as you would scroll to the right.
Clicking on an item would push the route to the single item view.

My problem consisted of 2 parts:

  1. The amount of data that each item included, it was fairly big json that was also passed to the single item view route on a click. To solve this I had to pass only the most vital data and make another request to load all the missing information after the route is loaded.
  2. By default, my list consisted of 10 items and would load more when you scroll. The more items there would be in the list the more it would take to push the route on click. Even though it didn’t looked like this could possibly be a problem with list being to big (it never seemed to be on a regular website that is used on desktop) it actually was. To solve this, I had to implement virtual scroll list to every list throughout the app (even if the list is like 5 items the difference is visible).

After solving these 2 problems my app became significantly faster. Clicking an item from the horizontal list now opens the new view nearly instantly and every other aspect of the app is much faster as well.

So, long story short - don’t pass a lot of data to your routes and use virtual scroll wherever possible.