[笔记]ng-repeat性能优化

前端之家收集整理的这篇文章主要介绍了[笔记]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'];
}]);

浏览器中运行的结果是:

《[笔记]ng-repeat性能优化》

此时我们通过增加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'
        }];
    }
}]);

增加了个按钮,用来改变数据。点击按钮,页面显示变化,控制台输出

《[笔记]ng-repeat性能优化》

我们发现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,总会对程序性能总是有些优化的。

猜你在找的程序笔记相关文章