Performance issue ng-if vs ng-show vs stateProvider


#1

Hello,

As my 1st step into Ionic world I wrote some application that contains 3 views based on $stateProvider. The goal was to check performance. For this purpose I took contact list + calendar (pretty big json content).

$stateProvider
    .state('groups', {
      url: '/groups',
      views: {
        'groups-tab': {
          templateUrl: 'partials/groups.html',
          controller: 'GroupsCtrl'
        }
      }
    })
    .state('group-detail', {
        url: '/group/:eventId',

      views: {
        'groups-tab': {
          templateUrl: 'partials/group-detail.html',
          controller: 'GroupDetailCtrl'
        }
      }
    })    
    .state('contacts', {
        url: '/contacts',      
      views: {
        'groups-tab': {
          templateUrl: 'partials/contacts.html',
          controller: 'ContactsCtrl'
        }
      }
    }); 
  $urlRouterProvider.otherwise('/groups');  

I use Nexus4 - 5

Even if I have static Json files stored in service, it takes me about 2 seconds to switch (aka redirect) between views. Because by this way we recreate all scopes (controllers).

I asked question about infinity list to up-down, I hope it will enter to next versions (i use 0.9.26 so far).

My next step was to leave for a while $stateProvider and create stand-alone controller (a.e one view) to verify two options:

  • ng-if
  • ng-show/ng-hide

The ngIf directive removes/recreates a portion of the DOM tree. ON false relevant elements are removed from the DOM, on true, a copy (lets say clone) of the element is re-inserted into the DOM.

So this way is similar to $stateProvider because we still rerun our controllers.

Therefore I implemented ng-show but got the ~same results. Its not surprise me because we only hide DOM elements but our controller continues to watch on any change/update and causes to additional delay.

I want to ask Ionic experts what you suggest to use in my case when each view has big list of items

(BTW, all stuff I load from service/factory after preloaded from native platform)

Thanks,


#2

I’m not an Ionic expect. However, bindonce really helped with my app. I list all a user’s contacts. On my test devices, I have > 500 contacts, my bindonce, they display immediately. Without bindonce, the rendering was about 1 sec.

Ionic has an implementation of “infinite scrol”. You might want to consider using it instead.


#3

Yes, i use bindonce. this is what Im going to use - infinite scrol.

The strange thing is when I use directive to catch render finish - only after one minute I see the results.

 if (scope.$last) { // all are rendered
            scope.$eval(attrs.repeatDone);
        }

Continue to investigate…

Can you post ng-repeat of your contacts?

This is what I use so far:

<div bindonce ng-repeat="contact in visible_contacts | orderBy:predicate:reverse | contactsFilter:searchKey" 
             class="item item-button-right item-thumbnail-left">
            <img bo-src="'img/default.png'">  
            <h2>{{ contact.displayName }}</h2>
            <h4>{{ contact.emails }}</h4>
            <button class="button button-clear" style="top: 33px"
                    ng-click="contactSelected(contact, $index)"
                    >
                <i class="icon" 
                   ng-class="{ 'ion-checkmark': !contact.selected, 'custom_checkmark': contact.selected }"
                   style="margin-right: 5%"></i>
            </button>
        </div>

Thanks,


#4

I’m not sure how much difference it will make, but you aren’t using bindonce to it’s full effect.

See if this helps:

<div bindonce="contact" ng-repeat="contact in visible_contacts | orderBy:predicate:reverse | contactsFilter:searchKey" class="item item-button-right item-thumbnail-left">
    <img bo-src="'img/default.png'">  
    <h2 bo-text="contact.displayName"></h2>
    <h4 bo-text="contact.emails"></h4>
    <button class="button button-clear" style="top: 33px"
            ng-click="contactSelected(contact, $index)"
            >
        <i class="icon" 
           bo-class="{ 'ion-checkmark': !contact.selected, 'custom_checkmark': contact.selected }"
           style="margin-right: 5%"></i>
    </button>
</div>