angular-ui / ui-grid

UI Grid: an Angular Data Grid
http://ui-grid.info
MIT License
5.39k stars 2.47k forks source link

How to Reduce the number of $watches created by ui-grid #4554

Open eladh opened 8 years ago

eladh commented 8 years ago

Hello :-) first i just wanted to say thanks for this great project.

we integrated ui-grid as part of our table-grid , and for some unknown reason the amount of watches generated by the ui-grid is huge for the amount of data we trying to process.

for example : grid - 9 columns table with 20 rows of simple text based cells without any custom cell template

inspecting the $watches we getting amount of 960 watches.

trying to debug this issue we printed each element that has watch on him and most of the times we got this kind of elements :

[ div#1445359168448-19-uiGrid-001Z-cell.ui-grid-cell.ng-scope.ui-grid-coluiGrid-001Z, context: div#1445359168448-19-uiGrid-001Z-cell.ui-grid-cell.ng-scope.ui-grid-coluiGrid-001Z] and each cell element got 2-4 watches.

we used simple data structure with basic columnDefs (field + display name) .

in most of our cases we don't need to watch for chances in specific grid cells.

is there anything we can do to reduce the number of $watches created by ui-grid ?

thanks in advance, elad.

eladh commented 8 years ago

Hi :-)

from the documentation : http://ui-grid.info/docs/#/tutorial/316_dynamic_data_changes

"..... The general AngularJS approach is two way data binding. On every digest cycle every binding is evaluated to see if anything has changed, and updates made as appropriate.

ui-grid explicitly seeks to avoid this. The grid is intended to render large numbers of rows (10K plus), and if all of those rows were evaluated on every digest cycle the performance would be unworkable" 

Is there any way we can understand why this cell based $watches are created.

we used the following code snippet to see and check the watch count

// taken from http://ng.malsup.com/#!/counting-watchers
(function countAngularWatchers(angular) {
  var i, data, scope,
    count = 0,
    all =  [the location of the UI-GRID] 
    len = all.length,
    test = {};

  var mostWatchers = 0;

  function countScopeWatchers(scope, element) {
    test[scope.$id] = true;
    var n = scope.$$watchers.length;
    count += n;
    if (n > mostWatchers) {
      console.log('most watchers', n);
      console.log(element);
      mostWatchers = n;
    }
  }

  // go through each element. Count watchers if it has scope or isolate scope
  for (i = 0; i < len; i += 1) {
    var el = angular.element(all[i]);
    data = el.data();
    scope = data.$scope || data.$isolateScope;
    if (scope && scope.$$watchers) {
      if ( !test[ scope.$id ] ) {
        countScopeWatchers(scope, el);
      }
    }
  }
  console.log('this page has', count, 'angular watchers');
  return count;
}(window.angular));
YonatanKra commented 8 years ago

I've managed to reduce my grids to around 1000 watchers (I'm showing around 10 grids of around 50 rows each. It was mainly changing many bindings into one time bindings. I've found myself changing most of the templates, so this is my advice to you (I can't load the code here with the changes).

Ruud-cb commented 8 years ago

But what did you change to the templates @YonatanKra ? I also have in place the row,cell and header template and as well defining a cellClass for the columns. I took the default templates within the source code.

VioricaMihai commented 8 years ago

Hi @YonatanKra , Can you show me what did you change to the templates plese? I have the same problem in my application. Thank you.

Ruud-cb commented 7 years ago

Just switch to ag-grid guys, works like a charm and build with angular in mind.

On Oct 13, 2016, at 21:12, Tim Lukacik notifications@github.com<mailto:notifications@github.com> wrote:

@YonatanKrahttps://github.com/YonatanKra @Ruud-cbhttps://github.com/Ruud-cb @VioricaMihaihttps://github.com/VioricaMihai You can't do this unless your grid is so small there's no scrolling (and thus no virtualization) involved. ui-grid is reusing the same rows over and over again so if you are using 1 time binding it'll just display the same information as you scroll. I speak from experience!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/angular-ui/ui-grid/issues/4554#issuecomment-253609768, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AJkpCn3b1WtAPfvMsf53jMoMgbpaMGjoks5qzoJ_gaJpZM4GSUZg.

csvan commented 7 years ago

@Ruud-cb really nice of you to dump advertisements for other projects on this projects issue tracker.

For everyone else, here is a PR that will hopefully help performance somewhat: https://github.com/angular-ui/ui-grid/pull/5829

nitinayir8 commented 6 years ago

@eladh @YonatanKra @csvan can you please suggest a workaround to get $watches count below 2000, its a serious concern for our application which has gone live with UI grid component. Browser gets hang when we try to use expand all feature with 50 as pagesize for parent and subgrid.

NightlyFox commented 5 years ago

I do know that some of the built in ui-grid templates have unnecessary watches on them that can be taken away if you do not use certain features.

https://github.com/angular-ui/ui-grid/blob/master/packages/core/src/templates/ui-grid/ui-grid-row.html

Within the template above i removed the ng-class as well as the role and ui-grid continued to work fine.

chengwuchao commented 5 years ago

Is there any update?