Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AngularJS 性能优化 #28

Open
hjzheng opened this issue Aug 12, 2016 · 0 comments
Open

AngularJS 性能优化 #28

hjzheng opened this issue Aug 12, 2016 · 0 comments

Comments

@hjzheng
Copy link
Member

hjzheng commented Aug 12, 2016

AngularJS 性能优化

说到 AngularJS 的性能优化,一个很重要的点就是从 数据的脏检查 开始:

理解脏检查机制 参考 #27

  • $digest loop
  • $watch list ($$watchers)
  • $evalAsync queue ($$asyncQueue)

做一个试验,看看什么情况下,变量会被加入到 $$watchers 中

http://plnkr.co/edit/hDHmkdNjQQkdwscjouzE?p=preview

  • {{}}
  • 某些指令: ng-repeat ng-model ng-bind
  • $watch

再看看什么情况会触发脏检查

  • ng封装的DOM事件 (例如ng-click) 可以查看源码 ngEventDirectives 的定义
  • XHR响应事件 ($http)
  • 浏览器Location变更事件 ($location)
  • Timer事件($timeout, $interval)
  • 主动执行$digest()或$apply()

减少 $watch list 数量,有以下处理手段:

  1. 使用 ng-if 替换 ng-show 或 ng-hide
  2. 使用 单次绑定 例如: {{::name}} 单次绑定不会加入到 $$watchers 中

降低 $watch list 中表达式的复杂度

  1. $scope.$watch(watchExpression, modelChangeCallback), watchExpression可以是String或Function。
  2. 避免watchExpression中执行耗时操作,因为它在调用一次 $digest 方法都会执行2次。(这个可以参考我渣译的Build Your Own AngularJS
  3. 避免watchExpression中操作dom,因为它很耗时
  4. 避免深度watch $watch(watchExpression, listener, [objectEquality]) 不要使用第三个参数
  5. 对于集合使用 $watchCollection

减少触发 $digest loop

  1. ngModelOptions 官方API
  2. $httpProvider.useApplyAsync(true); angular的数据驱动与浏览器的 event loop #27 参考@kuitos的回答
  3. 减少在页面使用filter,例如 {{1288323623006 | date:'medium'}}

缩小 $digest 的影响范围

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

其他方面:

  1. ng-repeat 使用 track by
  2. ng-bind 优于 {{}} https://ng-perf.com/2014/10/30/tip-4-ng-bind-is-faster-than-expression-bind-and-one-time-bind/
  3. Disabled debug Info $compileProvider.debugInfoEnabled(false); https://docs.angularjs.org/guide/production#disabling-debug-data

参考资料:
https://docs.google.com/presentation/d/15XgHRI8Ng2MXKZqglzP3PugWFZmIDKOnlAXDGZW2Djg/edit#slide=id.g2a0ec7d53_00
https://www.ng-book.com/p/The-Digest-Loop-and-apply/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant