AngularJs ng-repeat 必须注意的性能问题

AngularJs 的 ng-repeat 让我们非常方便的遍历数组生成 Dom 元素,但是使用不当也会有性能问题。

在项目中我们使用 ng-repeat 加载完一个列表后,如果再次请求数据,然后过滤列表,代码可能会这么写:

<div ng-controller="Test">
<button ng-click="request()">请求新数据</button>
<div ng-repeat="user in users">
{{user.name}}
</div>
</div>

Controller 的代码:

app.controller('Test', function($scope) {
var users = [];
for (var i = 0; i < 100; i++) {
users[i] = {
id: i,
name: "User: " + i
};
}
$scope.users = users; $scope.request = function () {
// 从服务器加载新数据
var result = []; // 直接重新赋值给 users
$scope.users = result;
};
});

查看 ng-repeat 的源码可以发现,当 ng-repeat 的数组被替换时, 它默认并不会重新利用已有的 Dom 元素,而是直接将其全部删除并重新生成新的数组 Dom 元素:

// 将上次生成的所有 dom 移除
for (key in lastBlockMap) {
if (lastBlockMap.hasOwnProperty(key)) {
block = lastBlockMap[key];
elementsToRemove = getBlockElements(block.clone);
$animate.leave(elementsToRemove);
forEach(elementsToRemove, function(element) { element[NG_REMOVED] = true; });
block.scope.$destroy();
}
}

Dom 的频繁操作是非常不友好的,为什么 ng-repeat 不能利用已有的 dom 元素去更新数据呢?因为你没有把数组元素的标识属性告诉它,那么两次替换的时候它就没办法追踪了,我们可以看到 ng-repeat 往数组里每个元素加了一个 $$hashKey 的属性:

这个 key 是由 Angular 内部的 nextUid() 方法生成,类似数据库自增,但是是使用字符串。

现在我们明白了,因为每次替换数组都会导致 ng-repeat 为每个元素生成一个新 key, 所以根本没办法重用已有的 Dom 元素,那么我们可以使用下边的语法来避免这个问题:

<div ng-controller="Test">
<button ng-click="request()">请求新数据</button>
// 使用 track by 标识
<div ng-repeat="user in users track by user.id">
{{user.name}}
</div>
</div>

这样 ng-repeat 就用将其缓存起来啦,当然可能你的数组元素没有一个标识属性,如果元素数量不多那么可以接受,不然还是建议你手动为其生成一个标识属性。

 
分类: Web
标签: AngularJsng-repeat

AngularJs ng-repeat的更多相关文章

  1. Part 6 AngularJS ng repeat directive

    ng-repeat is similar to foreach loop in C#. Let us understand this with an example. Here is what we ...

  2. part 4 AngularJS ng src directive

  3. Part 15 AngularJS ng init directive

    The ng-init directive allows you to evaluate an expression in the current scope.  In the following e ...

  4. table sorting–angularjs

    1: <script type="text/javascript" ng:autobind 2: src="http://code.angularjs.org/0. ...

  5. [译]用AngularJS构建大型ASP.NET单页应用(三)

    原文地址:http://www.codeproject.com/Articles/808213/Developing-a-Large-Scale-Application-with-a-Single A ...

  6. [AngularJS] AngularJS系列(1) 基础篇

    目录 什么是AngularJS? 为什么使用/ng特性 Hello World 内置指令 内置过滤器 模块化开发 一年前开始使用AngularJS(以后简称ng),如今ng已经出2了.虽说2已完全变样 ...

  7. 从angularJS看MVVM

    javascript厚积薄发走势异常迅猛,导致现在各种MV*框架百家争雄,MVVM从MVC演变而来,为javascript注入了全新的活力.我工作的业务不会涉及到angularJS[ng]这么重量级的 ...

  8. angularJS看MVVM

    从angularJS看MVVM   javascript厚积薄发走势异常迅猛,导致现在各种MV*框架百家争雄,MVVM从MVC演变而来,为javascript注入了全新的活力.我工作的业务不会涉及到a ...

  9. js架构设计模式——从angularJS看MVVM

    javascript厚积薄发走势异常迅猛,导致现在各种MV*框架百家争雄,MVVM从MVC演变而来,为javascript注入了全新的活力.我工作的业务不会涉及到 angularJS[ng] 这么重量 ...

  10. 初步认识Angulajs

     Angulajs是一个MVC前段框架,项目中使用Angulajs必须按照框架的写法编写代码,可以统一代码规范易于后期代码的维护. M Model 模型-数据,V View 视图-表现层 HTML/C ...

随机推荐

  1. Linux内核分析(六)----字符设备控制方法实现|揭秘系统调用本质

    原文:Linux内核分析(六)----字符设备控制方法实现|揭秘系统调用本质 Linux内核分析(六) 昨天我们对字符设备进行了初步的了解,并且实现了简单的字符设备驱动,今天我们继续对字符设备的某些方 ...

  2. Timer Swing

    一个Swing的例子,按钮控件上中文出现乱码: 试了网上的设置Font,或将汉字使用new  String(str.getBytes(),"GBK")对展示的汉字进行编码.都无效. ...

  3. Android ADT Bundle(Eclipse with ADT) ADT R23

    ADT Bundle Platform Package Size MD5 Checksum Windows 32-bit adt-bundle-windows-x86-20140624.zip 377 ...

  4. Web采矿技术

      一.数据挖掘 数据挖掘是运用计算机及信息技术,从大量的.不全然的数据集中获取隐含在当中的实用知识的高级过程.Web 数据挖掘是从数据挖掘发展而来,是数据挖掘技术在Web 技术中的应用.Web 数据 ...

  5. Oracle 11g XE 是 Oracle 数据库的免费版本

    Oracle 11g XE 是 Oracle 数据库的免费版本,支持标准版的大部分功能,11g XE 提供 Windows 和 Linux 版本. 做为免费的 Oracle 数据库版本,XE 的限制是 ...

  6. POJ3690 Constellations 【KMP】

    Constellations Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5044   Accepted: 983 Des ...

  7. ArcPad 10 的安装和部署

    ArcPad它被安装在一个手持装置或业内外的移动终端ArcGIS产品,那ArcPad这是Esri软件产品,哦,不是硬件. 虽然优于ArcGIS Desktop功能复杂的乐趣,是对于野外作业.数据採集等 ...

  8. Web项目

    Eclipse部署Web项目(图文讲解)   讲解是在linux下完成的,但对windows系统,操作也是一样的,不要被吓到了 1.下载Eclipse

  9. 【SSH三框架】Struts2第一章的基础:第一次写Struts2规划

    今年八月,当已经SSH三架完成学业.然后,他感动Android开展.三个框架已经很长的时间做无用的东西.所以,如果你想花三四天的时间来复习一下,写在博客. 附带SSH整个jar包网盘下载:http:/ ...

  10. 【百度地图API】当地址解析失败时,如何调用search方法查找地址

    原文:[百度地图API]当地址解析失败时,如何调用search方法查找地址 有个朋友问我,当地址解析失败时,应该如何处理呢?比如,他想搜索“南宁市青秀区”. --------------------- ...