[笔记]ng-repeat性能优化
在AngularJS中,ng-repeat是一个我们经常用到的内置指令。 一、repeat报错我们都知道ng-repeat中的数组存在相同的项时,会照成指令的报错。例如: <div id="box" ng-controller="controller"> <div ng-repeat="a in data">{{ a }}</div> </div> app.controller('controller',['$scope',function($scope) { $scope.data = ['aaa','bbb','aaa','ddd']; }]); 浏览器中运行的结果是: 此时我们通过增加track by,就可以避免报错了。将repeat改成: <div ng-repeat="a in data track by $index">{{ a }}</div> 其实真正的原因是,repeat不允许数据集中存在两个相同Id的数据,对于数字或者字符串等基本数据类型来说,它的id就是它自身的值,而如对象等引用型的数据则不会有这个问题。 二、track by优化前面的属于一个插曲,后面的才是正文。 ng-repeat循环生成DOM的方式有两种,一是删除所有的DOM,重新生成新的DOM,二是重复利用前面的DOM,不直接删除DOM,而是修改DOM中的内容。 为了监听DOM的移除,增加DOMNodeRemoved的监听事件。 $('#box').on('DOMNodeRemoved',function(event) { // DOM节点被移除时触发 ? ? console.log('DOM remove'); }); 前面的例子中的数据太简单了,平常我们是不会repeat一个那么简单的变量的。加入我们现在是要循环一个对象数组。修改例子: <body ng-app="app" ng-controller="controller"> <div id="box"> <div ng-repeat="a in data">{{ a.name }}</div> </div> <button type="button" ng-click="changeData()">change Data</button> </body> app.controller('controller',function($scope) { $scope.data = [{ name: 'aaa' },{ name: 'aaa' },{ name: 'bbb' }]; $scope.changeData = function() { $scope.data = [{ name: 'aaa' },{ name: 'ccc' },{ name: 'bbb' }]; } }]); 多增加了个按钮,用来改变数据。点击按钮,页面显示变化,控制台输出: 我们发现repeat下对应的DOM都发生了删除及重新生成的过程。(6是因为还要加上三个注释节点) 一旦repeat的数据过多的话,这样的操作就会过于消耗性能。 修改数据,增加上唯一的标志id。(也可以直接使用$index,自定义id的话,方便改变顺序) <div ng-repeat="a in data track by a.id">{{ a.name }}</div> app.controller('controller',function($scope) { $scope.data = [{ name: 'aaa',id: 0 },{ name: 'aaa',id: 1 },{ name: 'bbb',id: 2 }]; $scope.changeData = function() { $scope.data = [{ name: 'eee',id: 0 },{ name: 'fff',id: 1 },{ name: 'ggg',id: 2 }]; } }]); 此时,点击按钮,我们发现并没有引起DOM的删除及添加,只是简单的数据修改。这样的修改方式要比前面全部删除的方式要高效的多。 其他情况测试:1、数据减少$scope.changeData = function() { $scope.data = [{ name: 'ddd',{ name: 'eee',id: 1 }]; } 减少修改后的数据,此时点击按钮后,只触发了两次DOM remove,也就是只是删除了多余的一个DOM。 2、顺序变化$scope.changeData = function() { $scope.data = [{ name: 'ddd',id: 34 },id: 54 }]; } 修改后两个数据的id值,点击按钮修改data后,发现还是触发了4次DOM remove事件。也就是repeat按照key值,决定DOM的删除还是重复利用。 三、总结在使用ng-repeat时,尽量都带上track by,总会对程序性能总是有些优化的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |