Angular性能优化
变化检测
Angular 对比 AngularJS 在变化检测上由原来的双向检测(父->子,子->父)变为了单向(父->子)。所以每一次变化检测都会确定性地收敛,一般页面即使有几千个组件,变化检测也可以做几毫秒内完成,所以大家开发时很少会遇到性能瓶颈。(即使是AngularJS也很少遇到瓶颈)

自然很多开发者其实对Angular变化检测不会去深入了解。什么是变化检测?Angular在什么时候会进行变化检测呢?

变化检测定义:检测组件模型的变化并重绘制对应的View。比如:按钮颜色变化了 -> 重绘制按钮。
例子:优化绘制10000 svg rect
@Component用onpush strategy进行性能提升
定义一个组件时,可以传入一个变化检测配置项为
changeDetection: 配置为默认变化检测组件会判断输入的值是否改变来决定是否重渲染当前的view,box组件的判断逻辑为
if 在不需要优化性能的时候,这样的变化检测判断完全没有问题。但10000个svg的变化检测耗时显然需要优化,这时候我们可以用onpush策略来减少变化检测的开销。onpush策略只判断输入的引用(如果是object)是否改变
if 这边发现一下子减少了两个比较操作。对于10000个svg来说,就是少了20000个比较操作。
代码变化:
// parent
利用ngzone优化
回到一开始的问题,什么时候进行变化检测?
- Events - User events like click, change, input, submit, …
- XMLHttpRequests - E.g. when fetching data from a remote service
- Timers - setTimeout(), setInterval(), because JavaScript
都是异步操作。异步操作引发模型变化,从而触发重渲染动作。Angular依赖NgZone来监听异步操作,并从根部执行变化检测。
ObservableWrapper这个svg例子中,每次拖拽改变的是box的坐标,我们可以通过暂时禁用变化检测来优化。box坐标通过直接改变box元素的属性来实现。
mouseDown数据:
不优化:11-14fps mouse move cost: 52-56 ms
Onpush优化:16-21fps mouse move cost: 24-30ms
Ngzone优化:35-45fps mouse move cost: ~0.5ms
代码:
kingfolk/Angular-Playground
reference
Making your Angular apps fast by thoughtramblog.thoughtram.io Zones in Angularblog.thoughtram.io

