I have a big problem with performance with a web application using AngularJS. I currently have a grid that renders an array of objects. It looks something like this.
<table data-md-table data-md-row-select="!hideCheckboxes" data-ng-model="row.selected"
md-progress="promise" class="border-r">
<thead ng-if="!hideHead" md-head data-md-order="" md-on-reorder="onReorder">
<tr md-row>
<th md-column md:order:by="mark" ><span>Title 1</span></th>
<th md-column data-md-order-by="desc" class="padder"><span>Title 2</span></th>
<th md-column data-md-order-by="period" class="padder" ><span>Title 3</span></th>
<th md-column data-md-order-by="instance" class="padder"><span>Title 4</span></th>
<th md-column data-md-order-by="endDate" class="padder"><span>Title 5</span></th>
<th md-column data-md-order-by="itemState" class="padder"><span>Title 6</span></th>
</tr>
</thead>
<!--Data table-->
<tbody md-body>
<tr md-row md:select="row" data-md-on-select="log" md-on-deselect="deselect"
data-ng-repeat="row in myArray.data">
<td md-cell>
{{row.mark}}
</td>
<td md-cell>
<b>{{row.desc}}</b>
</td>
<td md-cell>
{{row.period | date:'yyyy MMMM' : 'UTC'}}
</td>
<td md-cell class="txt-cnt">
{{row.instance}}
</td>
<td md-cell ng-if="row.inter === null">
<md-icon md-svg-src="icons/ic_keyboard_arrow_down_green_24px.svg"></md-icon>
{{row.fecCorrida | date:'dd/MM/yyyy'}}
<br/>
<md-icon md-svg-src="icons/ic_keyboard_arrow_down_red_24px.svg"
ng-if="row.endDate != null"></md-icon>
{{row.endDate | date:'dd/MM/yyyy'}}
</td>
<td md-cell ng-if="row.inter !== null">
<md-icon md-svg-src="icons/ic_keyboard_arrow_down_green_24px.svg"></md-icon>
{{row.fecCorrida | date:'dd/MM/yyyy HH:mm:ss'}}
<br/>
<md-icon md-svg-src="icons/ic_keyboard_arrow_down_red_24px.svg"
ng-if="row.endDate != null"></md-icon>
{{row.endDate | date:'dd/MM/yyyy HH:mm:ss'}}
</td>
<td md-cell style="width:100px">
<div ng-class="row.itemState"><b>{{row.itemState}}</b></div>
</td>
<td md-cell style="padding:0 23px 0 0">
<md-icon ng-if="row.itemState == 'En Curso'"
ng-click="updaterow(row)"
ng-class="{ 'running-update-agenda': row.updating }"
md-svg-src="icons/ic_refresh_24px.svg">
<md-tooltip md-direction="left">Update</md-tooltip>
</md-icon>
</td>
<td md-cell style="padding:0 23px 0 0">
<md-icon ng-click="toggleRightNavAgenda(row)" md-svg-src="icons/ic_list_grey_24px.svg"
ng-hide="row.itemState === 'PENDING'">
<md-tooltip md-direction="left">Detail</md-tooltip>
</md-icon>
</td>
<td md-cell style="padding:0 23px 0 0">
<md-tooltip md-direction="left">ON / OFF</md-tooltip>
<md-switch ng-model="row.off" aria-label="ON / OFF"
ng-change="on(row)" class="md-success md-body-1"
ng-class="{'md-checked': row.off}"
ng-value="row.off" ng-false-value="false" ng-true-value="true" style="margin: 0 !important;">
</md-switch>
</td>
<td md-cell style="padding:0 23px 0 0">
<md-icon class="{{row.itemState}}-boton play"
ng-hide="row.itemState === 'OK' || row.itemState === 'Working'"
ng-click="row.running || runProcess($index)"
md-svg-src="icons/ic_play_arrow_grey_24px.svg">
<md-tooltip md-direction="left">
Run
</md-tooltip>
</md-icon>
</td>
<td md-cell style="padding:0 23px 0 0">
<md-icon ng-if="row.itemState == 'En Curso'"
ng-click="correct(row)"
ng-class="{ 'running-update': row.updating }"
md-svg-src="icons/ic_build_24px.svg">
<md-tooltip md-direction="left">
Correct
</md-tooltip>
</md-icon>
</td>
</tr>
</tbody>
</table>
Some of these bindings won't change the rows, but some will. The cell that have md-icons
are buttons that cause the row's state to change, and render a different image in one of the other cells to let the user know the row is being processed.
I ran this function in the console and found that this page is keeping 15000 watches (!) overall, most of them (around 95%) within this grid alone. I've been reading about watches and $digest
in Angular, but apparently the only solutions are making the rows static or using some sort of pagination (which that client can't be convinced to use).
Is there anything else you'd recommend?