Ionic View transition flickering

There are problem with view transition in latest version, leaving view takes half display and overlap enter view, here bug localization
View animations in 1.0.0-beta.13, all is ok animation smooth


View animations in 1.0.1 flickering http://plnkr.co/edit/1LYhSNLo5fxzMg1uzVGY?p=preview, many stage and leaving views created in dom on transition with style translate3d(33%, 0, 0) and not removed (http://joxi.ru/gV2VRBdiBdDv2v.jpg)
On my ipad mini, 1.0.0-beta.13 working much faster than 1.0.1

1 Like

+1 ! My nav bar flickers a lot with last version, but if I get the beta 14 instead, it’s way better !

Anything new about this issue ? There are a lot of things that have been improved since beta 14 that I don’t want to lose !

BUMP. @svsool you didn’t find anything to fix this ?

This nav bar flicker, is that happening when switching between tabs (“ion-tabs”), and on an Android device?

If so then I may have a solution:

/*
    CSS styles to eliminate the annoying flickering header when changing tabs in an Ionic app on Android:
    http://forum.ionicframework.com/t/flickering-when-navigating-via-tabs-on-android/27281/2
*/
.platform-android .header-item.title {
    transition-duration: 0ms;
}
.platform-android .header-item.buttons {
    transition-duration: 0ms;
}

Thanks to:

5 Likes

@leob Thanks for trying to help :slight_smile:

I don’t have that issue when switching tabs but when loading a new page, simply the processing time of calculating the controller code and display the page… I worked a lot on the performances of my pages and it’s a little better, but still very poor UX speaking.

Are you testing in a browser with “ionic serve” or on a device, and if so what kind of device? Is it a very old Android device? Then Crosswalk might help?

The CSS fix I sent you helped me out on an issue I had with ion-tabs. Without the CSS fix, changing between tabs would be accompanied by a clearly visible “flicker” of the title/header bar which was extremely annoying and looked very, very unprofessional. It was totally unacceptable IMO, so the CSS fix made my day.

Now with other page clicks or transitions I don’t have a problem. I’m quite satisfied with the performance of Ionic for my app and the device on which I’m testing (Samsung Galaxy S3 Neo, June 2014) isn’t old but also isn’t really new. It runs Android 4.4.2 which certainly isn’t new.

(I tried Crosswalk on the device but didn’t see any advantages so I’m not using it for now)

What device are you testing on? And what kind of stuff are you doing in your controllers, is it heavy calculations or what, or are your views complex?

@leob I tested on my Nexus 5, which is a pretty great device to work with, I think. Of course I do test also in the browser with ionic serve -l. The flicker is here in both, but much more visible on the real device.

When I take a look at my controllers and such, I don’t find them that complicated. I use a lot of factories though, with a lot of functions in each, but I don’t think it has anything to do with that problem - even more when you know that beta 14 is improving that transition issue a lot !

I’m not using xwalk right now but I did once, didn’t notice any improvement, so I simply took it out. I don’t think it would help a 5.1 device anyway.

the main problem of flickering:

If you load async data or the scoe/view data changes a lot the device needs to render the transition and the changing data as well --> that is hard work.

if you enter a new view (forward-View) you can set a loading-variable --> hide all the changing content parts until the view is finally entered

$scope.entered = false;
$scope.$on("$ionicView.enter", function () { $scope.entered = true; });

I increased a lot of transition performance with that.

That looks very interesting ! If I understand well, you then use ng-if=“entered” in the view for every changing content’s nodes ? Or are you suggesting to add the code for loading in the function triggered by $ionicView.enter ?

First one and a ng-show should work as well, it depends what content is shown during transition and how many data is changing in that time.

An example:

I had a complex app with a very large and nested list.

  1. First View of that state --> content is hidden until ionivView.enter is called
  2. leaving the view --> on ionicView.beforeLeave i set a flag hide the content again
  3. show cached view --> content is hidden until ionivView.enter is called

The hiding part if you leave the state is not needed for most of the state, because the caching works well on normal sized content.

Annnnd with the flag you can show a loading-spinner until the transition has finished :wink:

1 Like

I will test this in the coming days, and report how it went. Thanks a lot !

Still not clear about the exact issue, here but this is what I do:

In my controller I use “$scope.$on(’$ionicView.beforeEnter’…” and there I load my data by calling a service (it’s coming from a Firebase database ultimately). While the data is loading I display an $ionicLoading (hourglass/overlay), this displays on top of my view which is already visible.

(the field are initially ‘empty’, which looks just fine while hidden under the overlay - no need to hide anything)

Most of the time I also cache the loaded data inside the factory, so that the next time I enter the view/controller it’s super fast (almost instantaneous). Even then I’d display the hourglass but it’s so fast that you don’t see it.

One essential part of the technique: while loading the data, I don’t load individual data elements into “$scope” because that would (might) trigger a digest every time. Instead, I use the “controller as vm” technique and then after loading the data I’m putting it into the “vm” variable in one assignment, like this:

vm.article = angular.extend({}, service.loadArticle($stateParams.articleId));

When doing it this way I have a great and smooth UX (with a fairly limited amount of data I must say).
No “lag”, flicker or bad performance whatsoever.

Previously I used “route resolves” as recommended by the (some) experts, but I refrain from that approach now. It resulted in a “blank” screen prior to the data being loaded, which looked unprofessional.

It made the view transitions seem laggy and the UX much less smooth than when I’m putting the service call/data load in the controller (see John Papa’s “activate” controller pattern).

Oh and if you have a big list then make sure to use ‘collection-repeat’ rather than the standard ng-repeat.

Very interesting food for my thoughts, thanks again. I also use Firebase as my backend, and will try your approach as well. I may have a heavier database than you, though.

I also discarded the “resolve” solution, completely unresponsive.

And collection-repeat made me dream at the beginning, but I must say, it’s so hard to use when your blocks are not static (like a lot of my data will be - it’s free text entered by users). I prefer sticking to ng-repeat with infinite-scroll for now. Native scroll activation in Android made that a completely viable solution as long as you don’t have thousands of lines, I think, anyway.

Okay that is very interesting and potentially relevant information for me!

Right now I don’t have a big database but i’m planning to add realtime messaging to my app and will use Firebase for that. So the messages will get updated in realtime through Firebase and I’d display them in a list.

(either collection-repeat, or I’ll follow your suggestion; are you already aware of the “track by” optimization?)

By the way, I added some info to my previous answer regarding the “controller as vm” pattern that I use. I refrain from putting every item individually into $scope. Instead, I transition to the view, put a spinner/backdrop on top, load and assemble the complete object, and then I put that into the “vm” variable in one go.

Interesting that for you the ‘route resolve’ thing also didn’t work out. It’s recommended in many blog posts by the ‘experts’ but for me it also didn’t work well, so as always you need to judge these things for yourself.

By the way, seeing that you’re also using Firebase: I have some intermittent connectivity issues with Firebase when testing on an Android device: Firebase timeouts, slow responses

Did you experience issues like this? How are your experiences with Firebase in general?

I have to say that apart from these (rare) issues I’m quite happy with Firebase in general. These intermittent connectivity issues are a bit scary though, I’m not sure how concerned I should be.

Hey, I’m currently focused on Firebase’s security rules for my app, so I will get back to that topic whenever I’m finished with that. Will give feedback on each and every advice you guys gave here, of course !

I’m aware of “track by”, yes, thanks. It’s absolutely necessary for performances.

I need to say I didn’t have any connectivity issues with FB during my tests on my Nexus 5, and if it was a wide issue there would be more fuss online about it, so I guess you shouldn’t be too worried about it. I hope, at least ! As far as I’m concerned, Firebase with AngularFire and its $extend capabilities are simply perfect for me. There are some services that are lacking, like push notifications handle linked to interactions with the database, or “triggers” that set actions to do whenever the database is updated, but overall it’s an amazing service.

Yes I also like Firebase a lot. I’ve also dabbled a bit with Parse.com but Firebase’s APIs and documentation look much more clean, simple and well thought out. The data model and the query model are simple and well conceived.

Parse is more of a “everything including the kitchen sink” thing but their docs and APIs looked much less well thought out (apparently it’s based on the philosophy of the Backbone framework, which doesn’t make much sense to an Angular developer).

And no realtime capabilities of course.

Yes, Firebase lacks some things (e.g. push notifications) but I think that’s a deliberate choice, and a good choice IMO, why would they add push notifications when everybody and their brother is already offering that.

I’m not too concerned about my (rare) connectivity issues. Seems to be an artifact of the test/debug process on this particular Android device and if it would really keep popping up then I could add some workarounds (build some timeout and retry logic into my services).

Yeah and I’m also planning on using the $extend capabilities of Firebase/AngularFire, it looks very powerful. Right now I’m only using the basic features of Firebase and it’s already looking good.

By the way, you’re talking about the lack of “triggers” in Firebase (I suppose as a way to trigger some piece of server side processing). Well i saw that they thought about that, they call it Firebase Queue:

I suppose this is just what you meant?

Nope, I was speaking about classical triggers, as in mysql or others… When something occurs, like an addition to the database, automatically do “this” (like populating another location of the database, for exemple). Since FB is denormalized DB, it would be very usefull - and I had confirmation from a FB dev that this is on their roadmap !

Haha I was a bit confused, this Firebase Queue thing is interesting but totally unrelated to ‘triggers’.

But, since Firebase is a realtime database, isn’t the “trigger” concept already built in, effectively?

I mean, you can connect a client (which can be a node.js server app, or whatever) to a Firebase ref, and then you can register an event listener which gets called when your data changes. In your node.js event listener you then simply perform the Firebase database updates that you want.

So, changes are pushed to you, instead of having to peek/pull all the time to check for changes. That’s the beauty of Firebase, and that amounts to having a “trigger” or not?

Sure, this would achieve the same effect, but I think Firebase should really be capable of doing almost everything (and more and more things as the time goes) without the need of a private server. Of course, that’s my own opinion…

Yes, I see what you mean. One thing which Parse.com does have and Firebase doesn’t is the ability to upload your own pieces of code which can be executed “in the cloud” (hosted by Parse.com).

Parse.com calls this “cloud code” and it’s simply a piece of Javascript living on their servers (you don’t need to host it yourself) which you can trigger from your client or which can be triggered automatically.

Firebase doesn’t have that right now so any ‘intelligent’ processing needs to live in your client or on a server that you host yourself.