AngularJS进行性能调优的7个建议


Posted in Javascript onDecember 28, 2015

 AnglarJS作为一款优秀的Web框架,可大大简化前端开发的负担。近日Sebastian Fröstl在一篇博文《AngularJS Performance Tuning for Long Lists》中表示AnglarJS在处理包含复杂数据结构的大型列表时,其运行速度会非常慢。他在文中同时分享了解决方案。下面为该文的译文。

AnglarJS很棒,但当处理包含复杂数据结构的大型列表时,其运行速度就会非常慢。这是我们将核心管理页面迁移到AngularJS过程中遇到的问题。这些页面在显示500行数据时本应该工作顺畅,但首个方法的渲染时间竟花费了7秒,太可怕了。

后来,我们发现了在实现过程中存在两个主要性能问题。一个与“ng-repeat ”指令有关,另一个与过滤器有关。

下文将分享我们通过不同的方法解决性能问题的经验,希望可以给你带来启示。

一、AngularJS 中的ng-repeat在处理大型列表时,速度为什么会变慢?

AngularJS中的ng-repeat在处理2500个以上的双向数据绑定时速度会变慢。这是由于AngularJS通过“dirty checking”函数来检测变化。每次检测都会花费时间,所以包含复杂数据结构的大型列表将降低你应用的运行速度。

二、提高性能的先决条件

时间记录指令

为了测量一个列表渲染所花费的时间,我们写了一个简单的程序,通过使用“ng-repeat”的属性“$last”来记录时间。时间存放在TimeTracker服务中,这样时间记录就与服务器端的数据加载分开了。

// Post repeat directive for logging the rendering time angular.module('siApp.services').directive('postRepeatDirective', ['$timeout', '$log', 'TimeTracker', function($timeout, $log, TimeTracker) { return function(scope, element, attrs) { if (scope.$last){ $timeout(function(){ var timeFinishedLoadingList = TimeTracker.reviewListLoaded(); var ref = new Date(timeFinishedLoadingList); var end = new Date(); $log.debug("## DOM rendering list took: " + (end - ref) + " ms"); }); } }; } ]); // Use in HTML: …

Chrome开发者工具的时间轴(Timeline)属性

在Chrome开发者工具的时间轴标签中,你可以看见事件、每秒内浏览器帧数和内存分配。“memory”工具用来检测内存泄漏,及页面所需的内 存。当帧速率每秒低于30帧时就会出现页面闪烁问题。“frames”工具可帮助了解渲染性能,还可显示出一个JavaScript任务所花费的CPU时 间。

  三、通过限制列表的大小进行基本的调优

缓解该问题,最好的办法是限制所显示列表的大小。可通过分页、添加无限滚动条来实现。

分页

分页,我们可以使用AngularJS的“limitTo”过滤器(AngularJS1.1.4版本以后)和“startFrom”过滤器。可以通过限制显示列表的大小来减少渲染时间。这是减少渲染时间最高效的方法。

// Pagination in controller $scope.currentPage = 0; $scope.pageSize = 75; $scope.numberOfPages = function() { return Math.ceil($scope.displayedItemsList.length/ $scope.pageSize); }; // Start from filter angular.module('app').filter('startFrom', function() { return function(input, start) { return input.slice(start); }; // Use in HTML // Pagination buttons{{$index + 1}}

如果你不能/不想使用分页,但过滤过程又很慢,这时一定要检查前五步,并使用“ng-show”隐藏掉多余的列表元素。

无限滚动条

如果你希望进一步了解该方法,可访问 http://binarymuse.github.io/ngInfiniteScroll/

四、七大调优法则

1. 渲染没有数据绑定的列表

这是最明显的解决方案,因为数据绑定是性能问题最可能的根源。如果你只想显示一次列表,并不需要更新、改变数据,放弃数据绑定是绝佳的办法。不过可惜的是,你会失去对数据的控制权,但除了该法,我们别无选择。进一步了解: https://github.com/Pasvaz/bindonce。

2.不要使用内联方法计算数据

为了在控制器中直接过滤列表,不要使用可获得过滤链接的方法。“ng-repeat”会评估每个 [$digest(http://docs.angularjs.org/api/ng.$rootScope.Scope#$digest)%5D表达式。在我们的案例中,“filteredItems()”返回过滤链接。如果评估过程很慢,它将迅速降低整个应用的速度。

//这并不是一个好方法,因为要频繁地评估。

//这是要采用的方法

3.使用两个列表(一个用来进行视图显示,一个作为数据源)

将要显示的列表与总的数据列表分开,是非常有用的模型。你可以对一些过滤进行预处理,并将存于缓存中的链接应用到视图上。下面案例展示了基本实现过程。filteredLists变量保存着缓存中的链接,applyFilter方法来处理映射。

/* Controller */ // Basic list var items = [{name:"John", active:true }, {name:"Adam"}, {name:"Chris"}, {name:"Heather"}]; // Init displayedList $scope.displayedItems = items; // Filter Cache var filteredLists['active'] = $filter('filter)(items, {"active" : true}); // Apply the filter $scope.applyFilter = function(type) { if (filteredLists.hasOwnProperty(type){ // Check if filter is cached $scope.displayedItems = filteredLists[type]; } else { /* Non cached filtering */ } } // Reset filter $scope.resetFilter = function() { $scope.displayedItems = items; } /* View */Select active

{{item.name}}

4.在其他模板中使用ng-if来代替ng-show

如果你用指令、模板来渲染额外的信息,例如通过点击来显示列表项的详细信息,一定要使用 ng-if(AngularJSv. 1.1.5以后)。ng-if可阻止渲染(与ng-show相比)。所以其它DOM和数据绑定可根据需要进行评估。

以上内容给大家详解了AngularJS进行性能调优的7个建议,希望大家喜欢。

Javascript 相关文章推荐
javascript 中对象的继承〔转贴〕
Jan 22 Javascript
javascript支持firefox,ie7页面布局拖拽效果代码
Dec 20 Javascript
IE8 原生JSON支持
Apr 13 Javascript
jQuery lazyload 的重复加载错误以及修复方法
Nov 19 Javascript
5秒后跳转效果(setInterval/SetTimeOut)
May 03 Javascript
详解AngularJS控制器的使用
Mar 09 Javascript
AngularJs bootstrap搭载前台框架——准备工作
Sep 01 Javascript
jQuery实现的分页功能示例
Jan 22 Javascript
js实现三级联动效果(简单易懂)
Mar 27 Javascript
js+css实现全屏侧边栏
Jun 16 Javascript
Element Badge标记的使用方法
Jul 27 Javascript
javascript实现左右缓动动画函数
Nov 25 Javascript
浅析AngularJS Filter用法
Dec 28 #Javascript
jquery实现倒计时功能
Dec 28 #Javascript
基于jquery实现瀑布流布局
Jun 28 #Javascript
详解AngularJS Filter(过滤器)用法
Dec 28 #Javascript
原生JavaScript实现瀑布流布局
Jun 28 #Javascript
js实现瀑布流的三种方式比较
Jun 28 #Javascript
详解AngularJS中自定义过滤器
Dec 28 #Javascript
You might like
php注册和登录界面的实现案例(推荐)
2016/10/24 PHP
PHP用continue跳过本次循环中剩余代码的注意点
2017/06/27 PHP
Nigma vs Liquid BO3 第一场2.14
2021/03/10 DOTA
js有关元素内容操作小结
2011/12/20 Javascript
js indexOf()定义和用法
2012/10/21 Javascript
无缝滚动改进版支持上下左右滚动(封装成函数)
2012/12/04 Javascript
JavaScript调试技巧之console.log()详解
2014/03/19 Javascript
深入理解JavaScript系列(41):设计模式之模板方法详解
2015/03/04 Javascript
jquery实现点击弹出带标题栏的弹出层(从右上角飞入)效果
2015/09/19 Javascript
BootStrap制作导航条实例代码
2016/05/06 Javascript
JavaScript中三个等号和两个等号的区别(== 和 ===)浅析
2016/09/22 Javascript
Bootstrap基本布局实现方法详解
2016/11/25 Javascript
vue省市区三联动下拉选择组件的实现
2017/04/28 Javascript
javascript简单链式调用案例分析
2017/05/10 Javascript
详解vue-cli与webpack结合如何处理静态资源
2017/09/19 Javascript
在Create React App中使用CSS Modules的方法示例
2019/01/15 Javascript
[01:03:09]完美世界DOTA2联赛PWL S2 Forest vs SZ 第二场 11.25
2020/11/26 DOTA
python 字符串格式化代码
2013/03/17 Python
Python基于scrapy采集数据时使用代理服务器的方法
2015/04/16 Python
python 读入多行数据的实例
2018/04/19 Python
django2用iframe标签完成网页内嵌播放b站视频功能
2018/06/20 Python
新年快乐! python实现绚烂的烟花绽放效果
2019/01/30 Python
将python文件打包成EXE应用程序的方法
2019/05/22 Python
Python lambda表达式filter、map、reduce函数用法解析
2019/09/11 Python
Python代码块及缓存机制原理详解
2019/12/13 Python
美国内衣品牌:Leonisa
2016/08/14 全球购物
杠杆的科学教学反思
2014/01/10 职场文书
西式婚礼主持词
2014/03/13 职场文书
英文演讲稿开场白
2014/08/25 职场文书
小学重阳节活动总结
2015/03/24 职场文书
幼儿园教师师德师风承诺书
2015/04/28 职场文书
2015年团支部年度工作总结
2015/05/27 职场文书
MySQL 外键约束和表关系相关总结
2021/06/20 MySQL
「月刊Action」2022年5月号封面公开
2022/03/21 日漫
Java设计模式之代理模式
2022/04/22 Java/Android
Python使用plt.boxplot()函数绘制箱图、常用方法以及含义详解
2022/08/14 Python