Improvement #1:
As @Petr Averyanov suggested, use a variable instead of a function call.
instead of:
ng-repeat="serviceSchedule in getServiceScheduler(institutionUserConnection)"
change your logic to:
ng-repeat="serviceSchedule in preCalculatedServicesObjectInScope"
To do this, you need other logic changes in controller, you have to manage when the result of getServiceScheduler(institutionUserConnection)" actually changes yourself but it WILL increase the performance.
Improvement #2:
Use variables that are evaluated once if values of rows never change once they are rendered. This will reduce watchers drastically and help you improve overall performance:
```html
<tr ng-repeat="institutionUserConnection in someScopeVariable">
<td>{{ ::institutionUserConnection.user.firstname }} {{ ::institutionUserConnection.user.lastname }}</td>
</tr>```
Improvement #3:
Use track by statement in ng-repeat. Angular.js normally checks/tries to identify which object is which using a special hash function $id in ng-repeat. However, you naturally have an identifier for each object in array (and you should) you can make ng-repeat use this instead of creating it's own id. For example:
<tr ng-repeat="x in someScopeVariable track by x.id">
Improvement #4: (getting hackier here)
Whatever you do, since your array is large, you may not be able to increase the performance enough. Then you should ask this question, do people really see 600 items in one look? No, it won't fit to page. So, you can chop the part that doesn't fit the page, reducing DOM elements to be rendered at once. To do that you can use limitTo filter:
<tr ng-repeat="x in someScopeVariable | limitTo: visual.limitValue">
You can make visual.limitValue a reasonable count such as 10 in the beginning and you can increase it on table's scroll to increase it when use is about to reach the bottom, resulting partial appending of DOM to page. However this hack requires both style and code changes in the page.
Improvement #5: (hackiest one, but it works)
If dimensions of each row is constant, using scroll position and dimension of rows, you can calculate which rows should be visible and you can render them only. I've written a directive for practice, named it uber-repeat and tested it with 60.000 rows and performance was amazing, even in mobile phones!
I think there is a project uses somewhat same approach here: angular-vs-repeat