ng-repeat中调用函数与绑定数组的写法差异及性能分析
Key Differences Between the Two ng-repeat Patterns
Great question! These two ng-repeat patterns have significant differences when it comes to performance and how AngularJS handles change detection—let’s break them down clearly:
1. Performance & Change Detection Behavior
<div ng-repeat="item in getItems()">
This approach is a common performance trap, and here’s why:
- AngularJS runs digest cycles (its change detection system) constantly—after user clicks, AJAX responses, timers, and more. Every single digest cycle will call your
getItems()function. - Your
getItems()creates a brand new array every time it runs (Object.values(objA).concat(...)returns a fresh array instance, even ifobjAandobjBhaven’t changed at all). - ng-repeat checks if the array reference from the last digest matches the new one. Since they’re always different objects, it will destroy all existing list DOM elements and re-render every item from scratch—even if the actual data is identical. This wastes massive resources, especially with large lists, and causes noticeable UI jank.
- On top of that, running
Object.values()andconcat()on every digest adds unnecessary computation overhead.
<div ng-repeat="item in items">
This is the performant, recommended approach:
- ng-repeat only updates the list when the
itemsarray reference changes (or when Angular detects changes inside the array, like adding/removing items). - Since you manually update
itemsonly whenobjAorobjBactually changes, the array is only recreated and the list re-rendered when it truly needs to be. No unnecessary digest-triggered work or DOM updates.
2. Maintenance Tradeoff
- The
getItems()approach saves you from writing code to syncitemswithobjA/objBchanges, but this convenience comes at a steep performance cost. - The
itemsapproach requires extra code to keepitemsin sync with your source objects, but you gain full control over update timing—leading to a smoother user experience.
Pro Tip: Best of Both Worlds
If you want the convenience of automatic syncing without the performance hit, use AngularJS’s $watchGroup to update items only when objA or objB actually changes:
$scope.items = []; // Deep-watch objA and objB to catch nested property changes $scope.$watchGroup(['objA', 'objB'], function(newValues) { const [updatedObjA, updatedObjB] = newValues; $scope.items = Object.values(updatedObjA).concat(Object.values(updatedObjB)); }, true);
Now you can use <div ng-repeat="item in items"> and let Angular handle the syncing—no more unnecessary digest cycle computations!
内容的提问来源于stack exchange,提问作者Moshe Shaham
相关产品推荐
相关产品推荐

