angular的运行机制_Angular运行性能(Runtime Performance)优化指南

TL;DR

本文所提及的是Angular,即2.0版本之后的Angular,而不是AngularJS。

性能优化是我们的应用逐渐增大时都需要面对的问题,针对Angular的性能优化通常指两方面:加载性能优化和运行性能优化。

加载性能优化有很多种有效的方式,例如开启AOT编译、Lazy Loading、配置gzip等,这些方式都能减少应用体积从而缩短加载时间。

而本文讨论的主题是运行时性能优化。

为什么需要运行时性能优化

顾名思义,进行运行时性能优化当然是为了让Angular应用在使用时更加流畅、能有更好的用户体验。Angular自身的性能已经相当不错,在一些简单的界面场景中,我们无需做任何事情就已经拥有了很好的性能。但是随着开发工作的深入,界面内容逐渐变的越来越复杂,同一个界面中元素、组件数增多,我们发现我们的Angular应用已经没有之前那么流畅了。而如果你现在开发的正好是一个响应式网站,需要兼容不同的移动设备。而移动设备的硬件机能本身会相对PC会有一定差距,你会发现使用移动设备的浏览器访问自己的应用时,性能问题尤为明显。这时运行时性能优化就是一件尤为重要的事了。

Angular脏检查(Change Detection)机制

当我们遇到了性能问题,首先我们需要明白是什么导致我们的Angular应用变慢了。众所周知,在Angular中使用了双向绑定连接了model和DOM,当我们在component中改变了model的值,DOM中对应的值也会改变。但是Angular是怎么知道它需要在什么时候去更新DOM呢?这就是Angular Change Detection机制需要完成的事。

我们来看一个非常简单的例子:

例1

@Component({

template: `{ {count}}Add`

})

class AppComponent {

count = 0;

update() {

this.count++;

}

}

在这个例子中,我们每次点击Add按钮,界面上的count都会+1。其实界面上的更新并不是我们在component中执行了 this.count++之后就立刻发生的。我们看到Add按钮绑定了一个click事件,这个事件会执行`update`方法,Angular Change Detection机制会在这次click事件绑定的`update`方法执行完成之后检测模板中的数据绑定并且更新DOM中的相关数据。

在这里我做一个小的修改方便理解:

例2

@Component({

template: `{ {count}}Add`

})

class AppComponent {

count = 0;

update() {

this.count++;

// 在以下代码执行完毕之前DOM不会发生更新 for (let i = 0; i < 10000; i++) {

console.log(i)

}

}

}

我们在 update 方法中加入了一个循环去打印0到9999,在点击Add按钮之后,我们会发现界面上的数字并没有立刻更新,直到在console中打印完9999。由此可见在一次click事件完成之后Angular Change Detection才会去更新DOM。

我们再对update方法做一个改动

例3

update() {

this.count++;

setTimeout(() => {

this.count++;

}, 2000);

}

当我们再次点击Add按钮之后,我们发现数字加了1,这说明由click事件触发的Change Detection已经完成。过了两秒之后,数量再次加1,这说明setTimeout也会触发Change Detection。

而通常情况下,Angular Change Detection会由下几类事件触发:所有的浏览器事件(click, mouseover, keyup等)

Ajax异步请求

setTimeout()和setInterval()

一旦我们触发了这些事件,Change Detection机制就会开始运行。在这些事件所绑定的方法执行完成之后,Change Detection会根据当前模板中数据绑定的情况来更新DOM。

性能优化

当初步了解了Change Detection机制之后,我们就可以从此入手对我们的Angular应用开始优化。

在Web的大多数交互场景中我们使用最多的就是各种事件绑定,而我们在前面一节的内容也说明了一次Change Detection会随着事件的开始而开始。Event Handler就是我们在component中定义的与界面上各种事件所绑定的方法。(如之前一节我们给Add按钮的click事件绑定的update方法)Event Handler中就是我们的各种业务逻辑了。

所以每一个由事件引发的Change Detection生命周期可以大致看成如下几个步骤:

触发事件 -> Event Handler执行逻辑 -> Change Detection检测数据绑定并更新DOM -> 浏览器渲染

Angular的性能好坏就和每一次Change Detection周期的执行时间长短有关。理想情况下如果每次Change Detection周期能控制在17ms以内,那么界面将会十分流畅。而在这个周期中,触发事件是周期的开始,这个时间可以忽略不计。浏览器渲染是浏览器的行为,不受Angular控制。所以我们可以优化的就是在Event Handler执行和Chanege Detection检测绑定这两个步骤。

1、减少Event Handler的运行时间

Event Handler的运行时间无疑对我们的性能有着重要的影响,如上一节的*例2*所示,在我们Event Handler执行完成之前,界面会一直处于停滞状态,不会有任何更新。执行Event Handler之后Angular Change Detection才会去检测数据绑定,所以这也意味着Event Handler执行时,我们是掌握着应用的控制权的,因而这里的性能快慢完全是由我们自己所控。

因此当某些操作变慢时,我们就可以去调查这些操作所执行的Event Handler,找出执行慢的代码并对其优化。你也可以借助Chrome开发者工具中的Performance tool去检测界面上操作的性能,从而找出高耗时的操作,接着再针对相应Event Handler去优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值