이 경고는 클라이언트에서 하이드레이션을 활성화했지만 애플리케이션이 오랫동안, 즉 10초 넘게 안정화되지 않을 때 하이드레이션 과정 중 브라우저에만 표시됩니다.
일반적으로 페이지에 대기 중인 마이크로태스크나 매크로태스크가 있을 때 발생합니다.
Angular 하이드레이션은 애플리케이션이 안정화되었을 때 ApplicationRef.isStable이 보내는 신호를 다음과 같이 사용합니다.
- 서버 사이드 렌더링(SSR) 중에는 직렬화 과정을 시작합니다.
- 브라우저에서는 하이드레이션 후 정리 작업을 시작하여 연결되지 않은 DOM 노드를 제거합니다.
ApplicationRef.isStable이 10초 안에 true를 방출하지 않으면 이 경고가 표시됩니다. 이러한 동작이 의도한 것이고 애플리케이션이 나중에 안정화된다면 경고를 무시할 수 있습니다.
zone.js를 사용하는 애플리케이션
zone.js를 사용하는 애플리케이션은 여러 요인으로 인해 안정화가 늦어질 수 있습니다. 대기 중인 HTTP 요청, 타이머(setInterval, setTimeout), requestAnimationFrame을 계속 호출하는 로직 등이 원인이 될 수 있습니다.
매크로태스크
매크로태스크에는 setInterval, setTimeout, requestAnimationFrame 같은 함수가 포함됩니다.
애플리케이션 초기화 단계나 부트스트랩하는 컴포넌트에서 이 중 하나를 호출하면 애플리케이션이 안정화되는 시점이 늦어질 수 있습니다.
@Component({
selector: 'app',
template: ``,
})
class Simple {
constructor() {
setInterval(() => { ... }, 1000)
// 또는
setTimeout(() => { ... }, 10_000)
}
}
초기화 단계에서 이 함수들을 호출해야 한다면 Angular 존 밖에서 호출하여 문제를 해결할 수 있습니다.
class Simple {
constructor() {
const ngZone = inject(NgZone);
ngZone.runOutsideAngular(() => {
setInterval(() => {}, 1000);
});
}
}
서드 파티 라이브러리
일부 서드 파티 라이브러리도 오래 실행되는 비동기 작업을 생성하여 애플리케이션의 안정화를 지연시킬 수 있습니다. 앞서 설명한 것처럼 관련 라이브러리 코드를 존 밖에서 실행하는 것이 권장됩니다.
애플리케이션이 안정화된 뒤 코드 실행하기
애플리케이션이 안정화된 뒤에 비동기 작업을 설정하는 코드를 실행할 수 있습니다.
class Simple {
constructor() {
const applicationRef = inject(ApplicationRef);
applicationRef.isStable.pipe( first((isStable) => isStable) ).subscribe(() => {
// `isStable`은 참인 값을 Angular 존 밖에서 방출하므로
// `runOutsideAngular`를 사용할 필요가 없습니다.
// 거짓인 값은 Angular 존 안에서 방출합니다.
setTimeout(() => { ... });
});
}
}
존 없는 애플리케이션
존 없는 환경에서는 effect 안의 애플리케이션 코드가 무한 루프를 실행하거나 HTTP 요청이 대기 중이면 안정화가 늦어질 수 있습니다. effect 함수에서 사용하는 시그널이 계속 바뀌면 이런 무한 루프가 발생할 수 있습니다.
개발자는 PendingTasks 서비스를 사용해 애플리케이션의 안정 상태 판단에 명시적으로 참여할 수도 있습니다. 애플리케이션에서 이 API를 사용한다면 작업을 완료로 표시하는 함수를 반드시 호출하세요.