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 相关文章推荐
js中访问html中iframe的文档对象的代码[IE6,IE7,IE8,FF]
Jan 08 Javascript
window.requestAnimationFrame是什么意思,怎么用
Jan 13 Javascript
JS关键字球状旋转效果的实例代码
Nov 29 Javascript
AngularJS入门教程(一):静态模板
Dec 06 Javascript
jquery遍历函数siblings()用法实例
Dec 24 Javascript
JavaScript数组去重的两种方法推荐
Apr 05 Javascript
AngularJS指令详解及示例代码
Aug 16 Javascript
微信小程序 支付后台java实现实例
May 09 Javascript
详解Node.js amqplib 连接 Rabbit MQ最佳实践
Jan 24 Javascript
Vue 实现CLI 3.0 + momentjs + lodash打包时优化
Nov 13 Javascript
Vue.js 无限滚动列表性能优化方案
Dec 02 Javascript
Vue中实现回车键切换焦点的方法
Feb 19 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
完美解决令人抓狂的zend studio 7代码提示(content Assist)速度慢的问题
2013/06/20 PHP
一个PHP的ZIP压缩类分享
2014/05/04 PHP
thinkphp3.2.2实现生成多张缩略图的方法
2014/12/19 PHP
10个值得深思的PHP面试题
2016/11/14 PHP
Javascript条件判断使用小技巧总结
2008/09/08 Javascript
ExtJS扩展 垂直tabLayout实现代码
2009/06/21 Javascript
一个简单的js鼠标划过切换效果
2010/06/30 Javascript
js 控制页面跳转的5种方法
2013/09/09 Javascript
Jquery 过滤器(first,last,not,even,odd)的使用
2014/01/22 Javascript
js实现的GridView即表头固定表体有滚动条且可滚动
2014/02/19 Javascript
如何让浏览器支持jquery ajax load 前进、后退功能
2014/06/12 Javascript
node.js中RPC(远程过程调用)的实现原理介绍
2014/12/05 Javascript
jQuery给元素添加样式的方法详解
2015/12/30 Javascript
js 连续赋值的简单实现
2016/06/13 Javascript
原生js实现class的添加和删除简单代码
2016/07/12 Javascript
JavaScript数值千分位格式化的两种简单实现方法
2016/08/01 Javascript
jQuery实现可拖拽的许愿墙效果【附demo源码下载】
2016/09/14 Javascript
jquery 动态增加,减少input表单的简单方法(必看)
2016/10/12 Javascript
vue2 如何实现div contenteditable=“true”(类似于v-model)的效果
2017/02/08 Javascript
jQuery树插件zTree使用方法详解
2017/05/02 jQuery
详谈innerHTML innerText的使用和区别
2017/08/18 Javascript
JavaScript实现点击切换验证码及校验
2021/01/10 Javascript
详解Python核心对象类型字符串
2018/02/11 Python
运用PyTorch动手搭建一个共享单车预测器
2019/08/06 Python
Python一键查找iOS项目中未使用的图片、音频、视频资源
2019/08/12 Python
Python中内建模块collections如何使用
2020/05/27 Python
pyx文件 生成pyd 文件用于 cython调用的实现
2021/03/04 Python
CSS3 transition 实现通知消息轮播条
2020/10/14 HTML / CSS
美国办公用品购物网站:Quill.com
2016/09/01 全球购物
Tea Collection官网:一家位于旧金山的童装公司
2020/08/07 全球购物
优质飞蝇钓和渔具:RiverBum
2020/05/10 全球购物
常务副县长“三严三实”对照检查材料思想汇报
2014/10/05 职场文书
2014年建筑工程工作总结
2014/12/03 职场文书
董事长岗位职责
2015/02/13 职场文书
Spring中bean的生命周期之getSingleton方法
2021/06/30 Java/Android
springboot+WebMagic+MyBatis爬虫框架的使用
2021/08/07 Java/Android