转:AngularJS性能优化总结篇

前端之家收集整理的这篇文章主要介绍了转:AngularJS性能优化总结篇前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

AngularJS性能优化总结篇

本文针对的读者:

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

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

谈起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 });
  • 避免深度watch, 即第三个参数为true

    参考《mastering web application development with angularjs》 P313

  • 减少watch的变量长度
    如下,angular不会仅对{{variable}}建立watcher,而是对整个p标签
    双括号应该被span包裹,因为watch的是外部element

    参考《mastering web application development with angularjs》 P314

    <p>plain text other {{variable}} plain text other</>
    //改为:
    >plain text other <spanng-bind='variable'></span> plain text other<///或
    >{{variable}}</>

$apply vs $digest

  • $apply会使ng进入$digest cycle,并从$rootScope开始遍历(深度优先)检查数据变更。
  • $digest仅会检查该scope和它的子scope,当你确定当前操作仅影响它们时,用$digest可以稍微提升性能

    参考《mastering web application development with angularjs》 P308

延迟执行

  • 一些不必要的操作,放到$timeout里面延迟执行。
  • 如果不涉及数据变更,还可以加上第三个参数false,避免调用$apply
  • 对时间有要求的,第二个参数可以设置为0。
    $http.get('http://path/to/url').success((data){
    $scope.name = data.name;
    $timeout((){
    //do sth later,such as log
    },153)!important; border:0px!important; font-size:1em!important; outline:0px!important; float:none!important; vertical-align:baseline!important; position:static!important; left:auto!important; top:auto!important; right:auto!important; bottom:auto!important; height:auto!important; width:auto!important; line-height:1.1em!important; font-weight:bold!important; min-height:auto!important; background:none!important">false);
    });
  • $evalAsyncvs$timeout
  • 优化ng-repeat

    限制列表个数

    • 列表对象的数据转换,在放入scope之前处理。如$scope.dataList = convert(dataFromServer)
    • 可以使用ngInfiniteScroll来做无限滚动。在线示例

    使用 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为何不考虑此类场景)
    如下图,改为bindonceangular-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来分析性能

    相关工具

    原文链接:https://www.f2er.com/angularjs/149207.html

    猜你在找的Angularjs相关文章