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

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. 小程序组件化框架 WePY 在性能调优上做出的探究

    作者:龚澄 导语 性能调优是一个亘古不变的话题,无论是在传统H5上还是小程序中.因为实现机制不同,可能导致传统H5中的某些优化方式在小程序上并不适用.因此必须另开辟蹊径找出适合小程序的调估方式. 本文 ...

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

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

  8. 从angularJS看MVVM

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

  9. angularJS看MVVM

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

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

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

随机推荐

  1. printf那点事

    1.打印内存地址 #include<stdio.h> int main() { int a; printf("%p\n",&a); //%p打印地址,自己主动加 ...

  2. Android的相关的源代码的方法

    这里给大家介绍一个非常方便的相关法源代码. 1.打开Android SDK Manager.把你所使用的版本号的API给下载下来,例如以下图所看到的... 2.关联源代码时,将源代码关联到相应API的 ...

  3. (大数据工程师学习路径)第一步 Linux 基础入门----文件系统操作与磁盘管理

    介绍 本节的文件系统操作的内容十分简单,只会包含几个命令的几个参数的讲解,但掌握这些也将对你在学习后续其他内容的过程中有极大帮助. 因为本课程的定位为入门基础,尽快上手,故没有打算涉及太多理论内容,前 ...

  4. HDU 2647 Reward(图论-拓扑排序)

    Reward Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is comin ...

  5. projecteuler----&gt;problem=34----Digit factorials

    Problem 34 145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145. Find the sum of all number ...

  6. 从头开始学JavaScript (十一)——Object类型

    原文:从头开始学JavaScript (十一)--Object类型 一.object类型 一个object就是一系列属性的集合,一个属性包含一个名字(属性名)和一个值(属性值). object对于在应 ...

  7. 兼容Firefox和IE的onpropertychange事件oninput

    原文 兼容Firefox和IE的onpropertychange事件oninput onpropertychange能够捕获每次输入值的变化.例如:对象的value值被改变时,onpropertych ...

  8. Redhat Linux挂载NTFS格式的移动硬盘

    Redhat Linux挂载NTFS格式的移动硬盘 1. 选择下载ntfs-3g的源码包或rpm包 http://www.tuxera.com/community/open-source-ntfs-3 ...

  9. 【转】Appium 服务器端从启动到case完成的活动分析

    原文地址:http://blog.csdn.net/zhubaitian/article/details/39474151 此文的目的主要是通过分析Appium Server打印出来的log,加深对A ...

  10. 【百度地图API】发布静态图API啦!只需一个网址,即可展示定制百度地图!

    原文:[百度地图API]发布静态图API啦!只需一个网址,即可展示定制百度地图! 摘要: 百度地图静态图API!您无须执行任何“特殊”操作便可在网页上显示此图片. 不需要 JavaScript.我们只 ...