4

I have a problem of performance and i don't find the solution.

Context: I need to display a lot of data ( 500 lines, 8 columns ) in a table. To displayed this data i chosed to use Smart-table because it offers good functionality but the problem is that i have a lot of data and the time of displaying data is very long ( 5 - 9 second, this depend of device performance ).

Important thing: I need to display all data so i don't want pagination method, limit filter.

So this code is working :

    <ion-scroll class="scrollVertical" direction="xy" overflow-scroll="true" >
            <table st-table="tableaux" class="table table-striped">
                    <thead>
                        <tr>
                            <th ng-repeat="column in ColumnTable">{{column.Label}}</th>
                        </tr>
                        <tr>
                            <th ng-repeat="column in ColumnTable">
                                <input st-search="{{column.Id}}" placeholder="" class="input-sm form-control" type="search" ng-model="inputRempli"/>
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr ng-repeat="row in tableaux">
                            <td ng-repeat="column in ColumnTable" ng-init="colonne = column.Id">{{row[colonne]}}</td>
                        </tr>
                    </tbody>
                </table>
  </ion-scroll>

I read that Ionic made a directive (collection-repeat) wich allows an app to show huge lists of items much more performantly than ng-repeat. So i tried to remake my solution with collection-repeat but that doesn't work...

Code collection-repeat solution:

<ion-scroll class="scrollVertical">
        <table st-table="tableaux" class="table table-striped">
            <thead>
                <tr>
                    <th ng-repeat="column in ColumnTable">{{column.Label}}</th>
                </tr>
                <tr>
                    <th ng-repeat="column in ColumnTable">
                        <input st-search="{{column.Id}}" placeholder="" class="input-sm form-control" type="search" ng-model="inputRempli"/>
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr collection-repeat="row in tableaux"  item-width="200px" item-height="100px">
                    <td collection-repeat="column in ColumnTable" ng-init="colonne = column.Id" item-width="100px" item-height="100px">{{row[colonne]}}</td>
                </tr>
            </tbody>
        </table>
    </ion-scroll>

Error: Maximum call stack size exceeded

Questions: Is there any angularjs or ionic solution to increase performance of smart-table with a lot of data ? What's wrong with my collection-repeat ?

carton
  • 1,168
  • 9
  • 17
  • 1
    try to bind it once, ex: row in ::tableaux – Randyka Yudhistira May 28 '15 at 09:44
  • sorry to say that, but you are building a mobile app. On the UX point of view, that's not the best thing to display 500 lines with 8 columns each so I believe that this is your main problem to solve. – ThiagoPXP Jun 04 '15 at 06:42
  • I totaly agree with you that displaying 500 lines and 8 columns is not the the best thing to do. But the customers wants it... I don't know if there is one solution . – carton Jun 04 '15 at 07:10
  • what we generally do is.. first load 10 rows - show them and then in backend load remaining rows – harishr Jun 04 '15 at 17:01
  • This won't change, when it will display it will freeze until all data will be displayed – carton Jun 04 '15 at 17:02
  • your are not clear on what is exactly the cause of the performance issue: 1) httpLoading time (check network tab in dev tool and tell us how long your data takes to load (this can only be fixed by reducing the amount of data you load -> server side pagination) ? 2) UI freeze due to browser rendering performance (too many html nodes) ? I guess a bit of both – laurent Jun 05 '15 at 05:42
  • @laurent its freeze before displaying data – carton Jun 05 '15 at 06:58
  • You cannot improve loading time. If bind-once didn't help, this is not a problem of watchers, it's a problem of data being transferred. – Dave Alperovich Jun 05 '15 at 18:53
  • I'm not familiar with `collection-repeat` performance, but `ng-repeat` does not perform well when there are many items (let alone hundreds). My suggestion would be to replace the `ng-repeat` with a simple `for` loop (wrap it with a custom directive if you must). This should improve performance dramatically. Take into account though, that there might be rendering issues that cause the delay in the drawing, in which case the `ng-repeat` is not your biggest problem. It wouldn't hurt to try to optimize the rendering code as well. – ethanfar Jun 07 '15 at 04:24

2 Answers2

0

What version of Ionic are u using? If you are using version 1.0 beta 14 or higher use bind once (native in Angular 1.3)

It would like like this.

<ion-scroll class="scrollVertical" direction="xy" overflow-scroll="true" >
        <table st-table="tableaux" class="table table-striped">
                <thead>
                    <tr>
                        <th ng-repeat="column in ::ColumnTable">{{::column.Label}}</th>
                    </tr>
                    <tr>
                        <th ng-repeat="column in ::ColumnTable">
                            <input st-search="{{::column.Id}}" placeholder="" class="input-sm form-control" type="search" ng-model="inputRempli"/>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <tr ng-repeat="row in ::tableaux">
                        <td ng-repeat="column in ::ColumnTable" ng-init="colonne = column.Id">{{::row[colonne]}}</td>
                    </tr>
                </tbody>
            </table>
</ion-scroll>
rmuller
  • 1,837
  • 12
  • 12
  • Thanks for this answer but that doesn't change loading time (i tested on my smartphone and it load during 5 second to display it).Moreover if i do bind once my filter doesn't work. (I use lastest version of ionic ) – carton May 28 '15 at 09:52
0

How are you loading your datas ?

If you are doing a $scope.ColumnTable.push(newData); then this is not a proper way to do it.

What I do is :

  • create a service that load a Temporary Table : let's call it myService.setTable().

  • Inform your controller with an event : This service sends an event $rootScope.$broadCast("myService.setTable-refresh")

  • Catch the event into your controller & update table : $scope.$on('myService.setTable-refresh,function(){ $scope.myWorkingTable =myService.getTable();});

  • Update your HTML to work with myWorkingTable

Moreover, you shall define an unique key into your ng-repeat for performance optimisation used by track by to prevent rebuilding already created content.

See explanation here : http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm

Karlen Kishmiryan
  • 7,322
  • 5
  • 35
  • 45
aorfevre
  • 5,034
  • 3
  • 21
  • 51
  • Sorry for my late answer, my data is in an object in my service and i inject that service and call a function to get data. I think your solution could be good but it won't solve the problem of performance because only displaying data make performance problem. I already tried the track by issue and it is not really better. – carton Jun 02 '15 at 07:12