에러 백과

애플리케이션이 불안정한 상태로 유지됨

이 경고는 클라이언트에서 하이드레이션을 활성화했지만 애플리케이션이 오랫동안, 즉 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를 사용한다면 작업을 완료로 표시하는 함수를 반드시 호출하세요.