I've built a report which uses a set of nested ng-repeat directives to create what can be an enormous table. It works well to build the table, but after that, the scrolling performance is affected greatly - I assume this is due to what must be the large number of watches created by the ng-repeats.
The report only has to be built once and then is static. I don't need to watch the data continually.
I have two questions:
A) is there anyway to see a list of all the variables Angular is currently watching?
EDIT: This post was a great help in learning how to benchmark
B) Is there anyway to tell Angular to stop all of the watches it is doing? I've seen lots of posts about canceling watches which one sets up oneself, but that these are native directives, I'm not sure how I'd tap into them.
My preference would be to have a variable that I can say "if truthy, then do all watches, if not, then do not watch" or a function to just say "start watches" and "stop watches".
I have set up a very nice DOM watching service which can tell when all of the ng-repeats have executed, so I can know when I want to stop watching.
This is the table itself. Aside from tk-ng-repeat-completed, the other "tk-" attributes are just used for data and aren't actually directives.
<div class="table-responsive">
<table tk-sticky-column id="records" class="table table-striped table-hover table-condensed">
<!-- tbody[n] -->
<tbody class="dataset" ng-repeat="dataset in report.data track by $index" tk-ng-repeat-completed>
<!-- row[0] -->
<tr class="headline">
<!-- header[0] label -->
<th class="headline" style="background-color:#042E34;">
<div style="width:200px;"><h4>{{report.labels.y[$index]}}</h4></div>
</th>
<!-- header[n] label -->
<th ng-repeat="x_label in report.labels.x" tk-ng-repeat-completed
class="datapoint date"
tk-raw-data="{{x_label}}">
<em><small>{{x_label}}</small></em></th>
<!-- header[last] space for addition @todo remove this, add during calculations -->
<th class="date"></th>
</tr>
<!-- row[n] -->
<tr ng-repeat="(key, datapoints) in dataset" tk-metric-key="{{key}}">
<!-- column[0] label -->
<td tk-metric-key="{{key}}"
tk-calc="{{report.labels.data[key].calc}}"
class="rowdesc begin">{{key}}</td>
<!-- column[n] data -->
<td ng-repeat="datapoint in datapoints track by $index" tk-ng-repeat-completed
ypos="{{$parent.$parent.$parent.$index}}" xpos="{{$index}}" tk-metric-key="{{key}}"
class="datapoint"
tk-raw-data="{{datapoint}}">
{{datapoint}}</td>
</tr>
</tbody>
</table>
</div>
I've built a report which uses a set of nested ng-repeat directives to create what can be an enormous table. It works well to build the table, but after that, the scrolling performance is affected greatly - I assume this is due to what must be the large number of watches created by the ng-repeats.
The report only has to be built once and then is static. I don't need to watch the data continually.
I have two questions:
A) is there anyway to see a list of all the variables Angular is currently watching?
EDIT: This post was a great help in learning how to benchmark
B) Is there anyway to tell Angular to stop all of the watches it is doing? I've seen lots of posts about canceling watches which one sets up oneself, but that these are native directives, I'm not sure how I'd tap into them.
My preference would be to have a variable that I can say "if truthy, then do all watches, if not, then do not watch" or a function to just say "start watches" and "stop watches".
I have set up a very nice DOM watching service which can tell when all of the ng-repeats have executed, so I can know when I want to stop watching.
This is the table itself. Aside from tk-ng-repeat-completed, the other "tk-" attributes are just used for data and aren't actually directives.
<div class="table-responsive">
<table tk-sticky-column id="records" class="table table-striped table-hover table-condensed">
<!-- tbody[n] -->
<tbody class="dataset" ng-repeat="dataset in report.data track by $index" tk-ng-repeat-completed>
<!-- row[0] -->
<tr class="headline">
<!-- header[0] label -->
<th class="headline" style="background-color:#042E34;">
<div style="width:200px;"><h4>{{report.labels.y[$index]}}</h4></div>
</th>
<!-- header[n] label -->
<th ng-repeat="x_label in report.labels.x" tk-ng-repeat-completed
class="datapoint date"
tk-raw-data="{{x_label}}">
<em><small>{{x_label}}</small></em></th>
<!-- header[last] space for addition @todo remove this, add during calculations -->
<th class="date"></th>
</tr>
<!-- row[n] -->
<tr ng-repeat="(key, datapoints) in dataset" tk-metric-key="{{key}}">
<!-- column[0] label -->
<td tk-metric-key="{{key}}"
tk-calc="{{report.labels.data[key].calc}}"
class="rowdesc begin">{{key}}</td>
<!-- column[n] data -->
<td ng-repeat="datapoint in datapoints track by $index" tk-ng-repeat-completed
ypos="{{$parent.$parent.$parent.$index}}" xpos="{{$index}}" tk-metric-key="{{key}}"
class="datapoint"
tk-raw-data="{{datapoint}}">
{{datapoint}}</td>
</tr>
</tbody>
</table>
</div>
Share
Improve this question
edited May 23, 2017 at 12:10
CommunityBot
11 silver badge
asked Aug 12, 2015 at 20:50
dmgigdmgig
4,5685 gold badges39 silver badges48 bronze badges
4
- it can be 90 x 300. Which doesn't seem like a huge table but still slows down quite a bit. – dmgig Commented Aug 12, 2015 at 21:16
- I've seen much larger tables then that, perhaps there is something else going on. Can you put some of your code in? – Mathew Berg Commented Aug 12, 2015 at 21:18
- I hesitate to post all of it, because there is a lot to get lost in. A lot of formatting and things like that. There is a lot going on certainly. I guess if there was an answer for part A of my question it would help me benchmark things. – dmgig Commented Aug 12, 2015 at 21:22
- @MathewBerg I added the table, I'm not sure if that will indicate anything. – dmgig Commented Aug 12, 2015 at 21:31
1 Answer
Reset to default 25I'd recommend checking out the single-bind syntax they introduced in 1.3, if you're on a version greater than or equal to that one. It works really well and is very simple to implement. Here's an example:
normal syntax, which creates a watcher for each variable:
<div ng-repeat="foo in vm.bar">
{{foo}}
</div>
single-bind syntax, with no watcher on the nested variable inside the repeat:
<div ng-repeat="foo in vm.bar">
{{::foo}}
</div>
edit:
I forgot to mention that if your data isn't going to change at all after it gets populated the first time (e.g. from a $http.get), you can also just use the single-bind syntax on the top level ng-repeat:
<div ng-repeat="foo in ::vm.bar">
{{::foo}}
</div>