Zoneless Angular 설명 — Zone.js 없이 Change Detection이 작동하는 방식

발행: (2026년 1월 10일 오전 03:06 GMT+9)
5 min read
원문: Dev.to

Source: Dev.to

Introduction

수년간 Angular는 Zone.js에 의존해 자동으로 변경 감지를 트리거했습니다. UI를 동기화해 주었지만, 성능이 예측하기 어려워지고 디버깅이 복잡해졌습니다. 특히 Signals가 도입되면서 현대 Angular는 이제 Zone.js 없이도 동작할 수 있습니다.

What Zone.js Actually Did

Zone.js는 다음과 같은 비동기 API들을 몽키패치합니다:

  • setTimeout
  • Promise
  • fetch
  • DOM 이벤트

비동기 작업이 발생할 때마다 Angular는 자동으로 변경 감지를 실행했습니다. 이는 다음을 의미했습니다:

  • UI가 항상 동기화됨.
  • 관련 없는 컴포넌트라도 모든 비동기 이벤트가 변경 감지를 트리거할 수 있음.
  • 특히 대규모 애플리케이션에서 성능 튜닝이 추측에 의존하게 됨.

How Angular Works Without Zone.js

Zone.js를 제거하면 Angular는 더 이상 모든 비동기 이벤트마다 자동으로 변경 감지를 수행하지 않습니다. 대신 애플리케이션 상태가 변경되었을 때 직접 Angular에 알려야 합니다. 변경 감지는 Angular가 데이터가 바뀌었다는 것을 알 때만 실행됩니다. 방법은 다음과 같습니다:

  • Signals
  • Input 프로퍼티 변경
  • 명시적 트리거(예: ChangeDetectorRef)

Signals Overview

Signals는 Angular가 의존성을 자동으로 추적하도록 하는 반응형 원시 타입입니다.

// signal.ts
import { signal, computed, effect } from '@angular/core';

export class CounterComponent {
  count = signal(0);

  increment() {
    this.count.update(v => v + 1);
  }

  doubleCount = computed(() => this.count() * 2);

  constructor() {
    effect(() => {
      console.log('Count changed:', this.count());
    });
  }
}
Count: {{ count() }}
Double: {{ doubleCount() }}
  • Signal 업데이트: Angular는 정확히 무엇이 바뀌었는지 알고, 의존하는 뷰만 다시 렌더링합니다.
  • 전역 변경 감지 없음: Zone.js가 관여하지 않습니다.

Comparing the Old Zone‑Based Approach with the Zoneless Approach

Zone‑Based Example

// old.component.ts
setTimeout(() => {
  this.value = 10;   // Angular이 UI를 언제 업데이트할지 추측해야 함
}, 1000);

Zoneless Example Using Signals

// new.component.ts
value = signal(0);

setTimeout(() => {
  this.value.set(10);   // Signal 업데이트 → Angular 반응 → UI 업데이트
}, 1000);

Bootstrapping Without Zone.js

import { bootstrapApplication } from '@angular/platform-browser';
import { provideZoneChangeDetection } from '@angular/core';

bootstrapApplication(AppComponent, {
  providers: [
    provideZoneChangeDetection({
      eventCoalescing: true,
      runCoalescing: true
    })
  ]
});

Zone.js를 완전히 제거하려면:

  1. 프로젝트에서 zone.js import를 삭제합니다.
  2. 상태 변화에는 signals와 명시적 트리거를 사용합니다.
  3. 필요에 따라 ChangeDetectorRef 메서드를 호출해 수동으로 변경 감지를 수행합니다.

Zone.js가 없어도 Angular는 다음을 통해 반응성을 유지합니다:

  • Signal 업데이트
  • Input 바인딩
  • 이벤트 핸들러
  • 수동 ChangeDetectorRef 호출

When to Go Zoneless

  • 대규모 애플리케이션: 결정론적 렌더링과 불필요한 재렌더링 감소가 성능 디버깅을 용이하게 합니다.
  • RxJS 사용이 많은 레거시 앱: 트레이드오프를 고려하세요; Zoneless는 선택 사항이며 강제는 아닙니다.

Benefits of the Zoneless + Signals Model

  • 결정론적 렌더링 – 실제 데이터가 변한 곳에서만 업데이트가 발생합니다.
  • 재렌더링 감소 – 런타임 성능이 향상됩니다.
  • 성능 디버깅이 쉬워짐 – 숨겨진 Zone.js 부작용이 없습니다.
  • 현대적인 반응형 사고 모델 – 함수형 반응형 프로그래밍 개념과 일치합니다.

Conclusion

Zoneless Angular는 기능을 없애는 것이 아니라 추측을 없애는 것입니다.

  • Zone.js는 자동이지만 잡음이 많은 변경 감지를 제공합니다.
  • Signals + 명시적 트리거는 명확하고 빠르며 예측 가능한 업데이트를 제공합니다.

모든 곳에서 완전히 Zoneless하게 전환할 필요는 없지만, 그 작동 방식을 이해하면 더 나은 Angular 개발자가 될 수 있습니다.

Back to Blog

관련 글

더 보기 »