加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

转:AngularJS性能优化总结篇

发布时间:2020-12-17 10:04:06 所属栏目:安全 来源:网络整理
导读:AngularJS性能优化总结篇 本文针对的读者: 具备JavaScript性能优化的相关知识( 雅虎14条性能优化原则 、 《高性能网站建设指南》 等) 拥有angular实战经验。 Contents 1.脏数据检查 != 轮询检查更新 2.$digest后批量更新UI 3.提速 $digest cycle 3.1.关键

AngularJS性能优化总结篇

本文针对的读者:

  • 具备JavaScript性能优化的相关知识(雅虎14条性能优化原则《高性能网站建设指南》等)
  • 拥有angular实战经验。

Contents

  1. 1.脏数据检查 != 轮询检查更新
  2. 2.$digest后批量更新UI
  3. 3.提速 $digest cycle
    1. 3.1.关键点
    2. 3.2.优化$watch
    3. 3.3.$apply vs $digest
    4. 3.4.延迟执行
  4. 4.优化ng-repeat
    1. 4.1.限制列表个数
    2. 4.2.使用 track by
  5. 5.使用单次绑定
  6. 6.慎用filter
  7. 7.慎用事件
  8. 8.directive
  9. 9.使用Batarang来分析性能

脏数据检查 != 轮询检查更新

谈起angular的脏检查机制(dirty-checking),常见的误解就是认为: ng是定时轮询去检查model是否变更。
其实,ng只有在指定事件触发后,才进入$digest cycle

  • DOM事件,譬如用户输入文本,点击按钮等。(ng-click)
  • XHR响应事件 ($http)
  • 浏览器Location变更事件 ($location)
  • Timer事件($timeout,$interval)
  • 执行$digest()$apply()

参考《mastering web application development with angularjs》 P294

$digest后批量更新UI

传统的JS MVC框架,数据变更是通过setter去触发事件,然后立即更新UI。
而angular则是进入$digest cycle,等待所有model都稳定后,才批量一次性更新UI。
这种机制能减少浏览器repaint次数,从而提高性能。

参考《mastering web application development with angularjs》 P296
另,推荐阅读:构建自己的AngularJS,第一部分:Scope和Digest

提速 $digest cycle

关键点

  • 尽少的触发$digest(P310)
  • 尽快的执行$digest

优化$watch

  • $scope.$watch(watchExpression,modelChangeCallback),watchExpression可以是String或Function。
  • 避免watchExpression中执行耗时操作,因为它在每次$digest都会执行1~2次。
  • 避免watchExpression中操作dom,因为它很耗时。
  • console.log也很耗时,记得发布时干掉它。(用grunt groundskeeper)
  • ng-if vs ng-show, 前者会移除DOM和对应的watch
  • 及时移除不必要的$watch。(angular自动生成的可以通过下文介绍的bindonce

    参考《mastering web application development with angularjs》 P303~309

    1 varunwatch = $scope.$watch("someKey",function(newValue,oldValue){
    2 //do sth...
    3 if(someCondition){
    4
//当不需要的时候,及时移除watch
5 unwatch();
6 }
7 });

$apply vs $digest

延迟执行

优化ng-repeat

限制列表个数

使用 track by

刷新数据时,我们常这么做:$scope.tasks = data || [];,这会导致angular移除掉所有的DOM,重新创建和渲染。
若优化为ng-repeat="task in tasks track by task.id后,angular就能复用task对应的原DOM进行更新,减少不必要渲染。
参见:http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by

使用单次绑定

我们都知道angular建议一个页面最多2000个双向绑定,但在列表页面通常很容易超标。
譬如一个滑动到底部加载下页的表格,一行20+个绑定,展示个100行就超标了。
下图这个只是一个很简单的列表,还不是表格,就已经这么多个了:

但其实很多属性显示后是几乎不会变更的, 这时候就没必要双向绑定了。(不知道angular为何不考虑此类场景)
如下图,改为bindonce或angular-once后减少了很多:

update:
1.3.0b10开始支持内建单次绑定,238)">{{::variable}}
设计文档:http://t.cn/RvIYHp9
commit:http://t.cn/RvIYHpC
目前该特性的性能似乎还有待优化(2x slower)

更多相关单向绑定的说明:AngularJS1.3中的单向绑定、一次性数据绑定(one-time bindings)

慎用filter

在$digest过程中,filter会执行很多次,至少两次。
所以要避免在filter中执行耗时操作

参考《mastering web application development with angularjs》 P136

1 angular.module('filtersPerf''double'(){
2 return(input) {
3 //至少输出两次
4 console.log('Calling double on: '+input);
5 returninput + input;
6 };
7 });

可以在controller中预先处理

//mainCtrl.js
'mainCtrl'($scope,$filter){
$scope.dataList = $filter()(dataFromServer);
});

慎用事件

directive

使用Batarang来分析性能

相关工具

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

相关内容
推荐文章
站长推荐
热点阅读