변화 감지란 무엇인가요? 다음 글에서는 Angular의 변경 감지 메커니즘을 이해하고, 변경 감지의 작동 방식에 대해 이야기하고, Angular 변경 감지의 성능 최적화 방법을 소개합니다. 이 글이 모든 사람에게 도움이 되기를 바랍니다.
구성 요소의 데이터 상태가 변경된 후에는 이에 따라 뷰도 업데이트되어야 합니다. 뷰와 데이터를 동기화하는 이러한 메커니즘을 변경 감지라고 합니다. [관련 튜토리얼 추천: "angular Tutorial"]
비동기 작업(Events, Timer, XHR)이 발생하는 한 Angular는 상태가 변경되었을 수 있다고 생각하고, 변경 감지를 수행합니다.
NgZone
과 해당 포크 개체 Zone.js
를 소개합니다.
Zone.js
는 브라우저에서 비동기 활동을 캡슐화하고 가로채는 데 사용됩니다. 또한 비동기 수명 주기 후크NgZone
以及它的fork对象Zone.js
。
Zone.js
用于封装和拦截浏览器中的异步活动、它还提供 异步生命周期的钩子 和 统一的异步错误处理机制。
Zone.js
是通过 Monkey Patching(猴子补丁) 的方式来对浏览器中的常见方法和元素进行拦截,例如 setTimeout
和 HTMLElement.prototype.onclick
。Angular 在启动时会利用 Zone.js
修补几个低级浏览器 API,从而实现异步事件的捕获,并在捕获时间后调用变更检测。
Angular通过forkZone.js
并拓展出一个自己的区域NgZone
,让应用中的所有异步操作都会运行在这个区域中。
Angualr会为每一个组件生成一个变化监测器changeDetector
,记录组件的变化状态。
我们在创建了一个Angular 应用后,Angular 会同时创建一个 ApplicationRef
的实例,这个实例代表的就是我们当前创建的这个 Angular 应用的实例。 ApplicationRef
创建的同时,会订阅 ngZone 中的 onMicrotaskEmpty 事件,在所有的微任务完成后调用所有的视图的detectChanges()
来执行变更检测。
更新所有子子组件绑定的属性
调用所有子组件生命周期的钩子 OnChanges, OnInit, DoCheck,AfterContentInit
更新当前组件的DOM
调用子组件的变更检测
调用所有子组件的生命周期钩子 ngAfterViewInit
举个栗子,我们在开发模式的时候可能会遇到这种报错:
这是由于变更检测遵循从根组件开始,从上到下,执行每个组件的变更检测,直到最后一个组件达到稳定状态。而在下一次变更检测之前,子孙组件都不允许去修改父组件里的属性。
情况1 在开发模式下,Angular会进行二次检测 (生产环境下调用enableProdMode()
및 통합 비동기 오류 처리 메커니즘을 제공합니다.
Zone.js
는 Monkey Patching을 사용하여 setTimeout
및 HTMLElement.prototype.onclick
과 같은 브라우저의 일반적인 메서드와 요소를 가로챕니다. . Angular는 Zone.js
를 활용하여 시작 시 여러 하위 수준 브라우저 API를 패치하여 비동기 이벤트를 캡처하고 캡처 시간 이후 변경 감지를 호출합니다. Angular는 Zone.js
를 분기하고 자체 영역 NgZone
을 확장하므로 애플리케이션의 모든 비동기 작업이 이 영역에서 실행됩니다.
changeDetector
를 생성하여 구성 요소의 변경 상태를 기록합니다. ApplicationRef
의 인스턴스도 생성합니다. 이 인스턴스는 현재 생성 중인 Angular 애플리케이션의 인스턴스를 나타냅니다. ApplicationRef
가 생성되면 onMicrotaskEmpty 이벤트, 모든 마이크로태스크가 완료된 후 모든 뷰의 DetectChanges()
를 호출하여 변경 감지를 수행합니다. 변경 감지 실행 순서
모든 하위 하위 구성 요소에 바인딩된 속성 업데이트
enableProdMode()
가 호출되면 감지 횟수가 1로 줄어듭니다). 🎜4단계🎜를 완료한 후 하위 컴포넌트의 상위 컴포넌트 속성을 수정하면 Angular가 두 번째 감지를 수행하여 두 값이 일치하지 않는 것을 발견하면 위 오류가 발생합니다. 🎜🎜🎜🎜사례 2🎜🎜 상위 구성 요소가 하위 구성 요소에 속성을 바인딩하는 한 OnChanges, OnInit, DoCheck, AfterContentInit 및 AfterViewInit 사이의 수명 주기 후크에서 다음 코드가 실행되는지 여부에 관계없이 오류가 발생합니다. 보고됩니다. 🎜// #parent {{data}} <child [data]="data"></child> // in child component ts, execute: this.parent.data = 'new Value';🎜🎜변경 감지를 위한 실행 전략🎜🎜🎜🎜🎜🎜🎜🎜기본 전략🎜🎜🎜🎜
이벤트가 변경 감지(예: 사용자 이벤트, 타이머, XHR, 약속 등)를 트리거할 때마다 이 기본 전략은 구성 요소 트리의 모든 구성 요소를 위에서 아래로 확인합니다. 구성 요소 종속성에 대해 어떤 가정도 하지 않는 보수적인 검사 방법을 더티 검사라고 합니다. 이 전략은 너무 많은 구성 요소를 적용할 때 애플리케이션 성능에 영향을 미칩니다.
구성 요소 데코레이터의 changeDetection
을 수정합니다. OnPush 전략으로 설정한 후 Angular는 변경될 때마다 구성 요소와 구성 요소를 건너뜁니다. 구성 요소의 모든 하위 구성 요소에 대한 변경 감지가 트리거됩니다. changeDetection
,设置为 OnPush 策略后,Angular 每次触发变化检测后会跳过该组件和该组件的所以子组件变化检测。
在 OnPush
策略下,只有以下这几种情况才会触发组件的变化检测:
由于组件默认执行 Default策略 ,任何异步操作都会触发整个组件数从上到下的检查。即使Angular团队不断提升性能,可以在毫秒内完成上百次检测,但是当应用拓展至百上千个组件组成时,庞大的组件树对应的变更检测也会达到性能瓶颈。
此时,我们就需要开始分析并减少不必要的检测次数。
区域污染(Zone Pollution)
一般我们在生命周期钩子里使用第三方库,比如chart类库初始化,会自带requestAnimationRequest/setTimeout/addEventListener,我们可以将初始化方法写入NgZone
的runOutsideAngular
方法中。
OnPush 策略
对于不涉及更新操作的视图可以剥离出组件,使用onPush策略,以通知更新的方式刷新视图(见上方 变更检测的执行策略 部分)。
用 pure pipe 代替 {{function(data)}}
在html文件内,{{function(data)}}
OnPush
전략에서는 다음 상황에서만 구성 요소 변경 감지가 트리거됩니다.
setTimeout()
🎜Promise.resolve().then()🎜🎜🎜🎜this.http.get('...').subscribe()🎜🎜🎜🎜🎜🎜수동으로 변경 감지 트리거🎜(각 구성 요소는 구성 요소와 연결됩니다.) ViewChangeDetectorRef)NgZone
의 runOutsideAngular
메서드에 초기화 메서드를 작성할 수 있습니다. 🎜🎜🎜🎜🎜 🎜🎜🎜🎜OnPush 전략🎜🎜🎜업데이트 작업과 관련되지 않은 뷰의 경우 구성 요소를 분리하고 onPush 전략을 사용하여 업데이트를 알림으로써 뷰를 새로 고칠 수 있습니다(위의 🎜변경 감지를 위한 실행 전략🎜 섹션 참조). 🎜🎜🎜🎜🎜 🎜🎜🎜🎜순수 파이프🎜 대신 {{function(data)}}🎜🎜🎜html 파일에서 {{function(data)}}
작성 방법으로 인해 모든 값이 변경 감지가 발생할 때마다 변경됩니다. (?: 1000개의 항목 목록이 있을 때 1개의 데이터만 수정하면 되지만, 업데이트할 필요가 없는 나머지 999개의 데이터도 다시 계산됩니다.)🎜🎜이때, 파이프 방식에서는 변경된 값만 작업이 트리거되어 일부 보기를 업데이트합니다. 🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜많은 양의 데이터를 렌더링해야 하는 경우 가상 스크롤/페이지 매김을 선택하여 데이터를 요청하세요🎜🎜🎜위 4가지 해결 방법은 🎜Angular 팀🎜 소개 영상에서 나왔습니다. 동영상에서 Angular devtool은 횟수를 계산하고 문제를 분석하고 해결하는 데 사용됩니다. 따라서 Angular가 9 이상인 경우 Angular devtool 설치 및 실행 방법을 알아보려면 계속 읽어보세요. 🎜
// environment.dev.ts ... production: false ...
"optimization": false
projects > your-project-name > architect > build > configurations > dev > "optimization": false
更多编程相关知识,请访问:编程教学!!
위 내용은 Angular의 변경 감지 메커니즘에 대한 간략한 분석과 성능을 최적화하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!