AngularJS在大型单页面应用中的性能优化(一)
发布时间:2020-12-17 09:44:25 所属栏目:安全 来源:网络整理
导读:1. 简介 无论你正在编写一个旧的应用程序还是在一个大型应用中采用AngularJS,性能是一个重要的方面。了解是什么原因导致AngularJS应用程序慢下来非常重要,要知道,在开发过程中做出权衡是很重要的。本文将介绍一些AngularJS比较常见的性能问题,以及优化的
1. 简介无论你正在编写一个旧的应用程序还是在一个大型应用中采用AngularJS,性能是一个重要的方面。了解是什么原因导致AngularJS应用程序慢下来非常重要,要知道,在开发过程中做出权衡是很重要的。本文将介绍一些AngularJS比较常见的性能问题,以及优化的建议。 2. 性能测试工具本文采用jsPerf http://jsperf.com/ 性能测试的基准。 3. 软件性能评价软件性能有两个基本的因素: 首先是算法的时间复杂度。一个简单的例子就是线性搜索和二分检索有着非常显著的性能差距。 第二个软件缓慢的原因被称为空间复杂度。这是一台电脑需要多少“空间”或内存运行你的应用程序。内存需求越多,运行速度就越慢。 4 Javascript的性能有些性能问题不仅仅是Angular带来的,而是JavaScript本来就有的。 4.1 循环避免在循环内部调用函数,可以移到外部调用。 var sum = 0; for(var x = 0; x < 100; x++){ var keys = Object.keys(obj); sum = sum + keys[x]; } 上面的方面明显没有下面的快: var sum = 0; var keys = Object.keys(obj); for(var x = 0; x < 100; x++){ sum = sum + keys[x]; } 4.2 DOM访问在获取DOM元素时要注意 angular.element('div.elementClass') 这种方式是非常昂贵的。其实这在AngularJS中并不会引起太大的问题。但是留意一下是有好处的。DOM树要小,DOM的访问要尽可能的少。 4.3 变量作用范围垃圾回收把你的变量作用范围限制地越紧密越好,这样垃圾回收器就可以更快地回收空间。注意下面的问题: function demo(){ var b = {childFunction: function(){ console.log('hi this is the child function') }; b.childFunction(); return b; } 当这个函数终上了,这里就没有到b的引用。b就会被回收了。但是如果有这样一行: var cFunc = demo(); 这个引用就会阻止垃圾回收。要尽量避免这类引用。 4.4 数组和对象这里有很多点: 比如: for (var x=0; x<arr.length; x++) { i = arr[x].index; } 比这一种快一点(注* arr为数组, obj为json对象) for (var x=0; x<100; x++) { i = obj[x].index; } 比这一种更快一点 var keys = Object.keys(obj); for (var x = 0; x < keys.length; x++){ i = obj[keys[x]].index; } 测试 : http://jsperf.com/array-vs-object-perf-demo 5 重要的概念我们已经讨论过有关JavaScript的性能,现在有必要看一看AngualrJS中的核心概念,看看它究竟是怎么运作的。 5.1 域(Scopes)和更新周期(Digest Cycle)Angular的域本质上是一些JavaScript对象,它们从一些预定义的对象继承而来。基本上,小的域比大的域运行要快。 换句话说,每创建一个新的域,都会给垃圾回收器添加更多待回收的内容。 在写AngularJS应用中尤其要注意的一个核心概念和性能影响方面是更新周期(Digest Cycle)。实际上每一个域都会存放一个由方法组成的数组 $$watchers。 每当域中的一个值(属性)或绑定的DOM,如 ng-repeat,ng-switch 和 ng-if 等等,调用 $watch 时,一个函数(function)就会添加到相对应域中的$$watchers数组队列中。 当域中的值发生改变时,在$$watchers中所有的watchers函数都会被触发调用。并且当它们的任何一个修改了域中的某个值时,它们会被再次触发执行。 这个过程会一直循环下去直到$$watcher数组队列中不再做任何更改或抛出异常为止。 更外如果任何代码执行$scope.$apply(),都会触发更新周期。 最后一点是 $scope.evalAsync() 会在一个异步调用中执行,并且在当前和下个执行周期中,不会调用其的更新周期。 6. 在设计Angular时应该遵守的一般准则6.1 大型对象和服务器调用所以这些都告诉了我们什么?首先我们要尽可能地简化我们的对象。当对象是从服务器返回时,这一点尤为重要。 直接将数据库中的一行转换成对象只是临时性方案,因此不要使用.toJson(). 只需要把Angular需要的属性值返回回来。 6.2 监视函数(Watching Functions)另一个常见的问题是为观察者绑定的函数。不要将任何东西(ng-show,ng-repeat等等)直接绑定到一个函数。不要直接监视任何函数的返回值。该函数会在每个更新周期都执行,可能会降低你应用的速度。 6.3 监视对象(Watching Objects)同样,Angular提供了第三个可选参数来监视整个对象的改动。将调用$watch的第三个参数设为true。这是一个非常可怕的想法。一个更好的解决办法是依靠服务和对象的引用,监视域之间的变化。 注* 相关阅读 AngularJS在大型单页面应用中的性能优化(二) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |