MST

星途 面试题库

面试题:Angular的变更检测机制及其优化策略

详细说明Angular的变更检测机制,包括何时触发、如何检测变化。并讨论在大型应用中,你会采用哪些优化策略来提高变更检测的性能,比如如何利用OnPush策略以及不可变数据结构。
24.3万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

Angular变更检测机制

  1. 何时触发
    • 事件触发:当用户与页面进行交互,如点击按钮、输入文本等DOM事件发生时,Angular的变更检测机制会被触发。
    • Promise或Observable异步操作完成时:当Promise被resolved或rejected,或者Observable发出新的值时,变更检测也会启动。例如,通过HttpClient发起HTTP请求获取数据后,响应数据返回时会触发变更检测。
    • setTimeout和setInterval:使用JavaScript原生的setTimeoutsetInterval时,当回调函数执行,也会触发变更检测。
  2. 如何检测变化
    • 脏检查机制:Angular使用脏检查机制来检测变化。它从根组件开始,遍历组件树,检查每个组件的输入属性(@Input())和绑定的属性(如[ngModel]等)。对于每个组件,它会比较当前值和上一次检查的值。如果发现有任何值发生了变化,就认为该组件“脏了”,需要更新视图。
    • 检查顺序:先检查组件的输入属性,然后检查模板表达式,包括插值({{}})、属性绑定([attr])、事件绑定((event))等。

大型应用中提高变更检测性能的优化策略

  1. 利用OnPush策略
    • 原理:将组件标记为ChangeDetectionStrategy.OnPush时,Angular会优化该组件的变更检测。只有在以下情况下,该组件及其子组件才会触发变更检测:
      • 组件接收到新的输入值(引用变化)。例如,如果输入是一个对象,当对象的引用改变时(而不是对象内部属性改变),才会触发变更检测。
      • 组件触发了一个事件,如按钮点击事件。
      • 从Observable中接收到新的值,前提是该Observable是使用observeOn调度到Angular的NgZone(默认情况下,HttpClient返回的Observable满足此条件)。
    • 使用方法:在组件的@Component装饰器中设置changeDetection: ChangeDetectionStrategy.OnPush。例如:
import { Component, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app - my - component',
  templateUrl: './my - component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponent {}
  1. 不可变数据结构
    • 原理:使用不可变数据结构可以减少不必要的变更检测。因为当数据是不可变的,每次数据变化都会创建一个新的对象或数组,而不是修改原有对象。这使得Angular可以通过简单的引用比较(===)来判断数据是否发生了变化。如果引用没有改变,Angular就认为数据没有变化,不会触发不必要的变更检测。
    • 使用方法:在JavaScript中,可以使用Object.freeze创建不可变对象,或者使用像immer这样的库来更方便地处理不可变数据。例如,使用immer更新数组:
import produce from 'immer';

const initialArray = [1, 2, 3];
const newArray = produce(initialArray, draft => {
  draft.push(4);
});
  • 在组件中使用不可变数据时,确保将新的不可变数据赋值给输入属性,而不是直接修改原有数据。这样可以利用OnPush策略和引用比较来优化变更检测。