본문 바로가기

개발 공부/Angular

컴포넌트 인클루전 방식 vs 라우트 분리 방식

Angular에서 컴포넌트를 동적으로 렌더링할까? 라우트로 분리할까?

 

 

앵귤러로 SPA(Single Page Application)를 개발하다 보면, 화면 전환을 어떻게 구성할지에 대한 고민이 꼭 생깁니다

"<app-example> 컴포넌트로 렌더할까? 아니면 route를 따로 만들어서 이동시키는 게 좋을까?"

 

결론부터 말하자면 "경우에 따라 다르다" 입니다.

두 방식 모두 장단점이 분명하며, 상황에 따라 선택이 달라져야 합니다. 

 


1. 컴포넌트 인클루전 방식

<!-- main.component.html -->
<app-tab-one *ngIf="selectedTab === 'one'"></app-tab-one>
<app-tab-two *ngIf="selectedTab === 'two'"></app-tab-two>


// main.component.ts
ngOnInit() {
  this.activatedRoute.queryParams.subscribe(params => {
    this.selectedTab = params['tab'] ?? 'one';
  });
}

 

장점

  • 하나의 라우트에서 UI를 동적으로 전환할 수 있어 UX가 빠르고 부드럽다.
  • DOM이 유지된 상태에서 상태를 전환하므로 리렌더링 비용이 적고, 복잡한 상태 전달도 용이.
  • 내부 탭이나 모달처럼 URL 구조가 중요하지 않은 경우 빠른 개발이 가능.

단점

  • URL만 봐서는 어떤 화면인지 알기 어렵다. (/main?tab=one → 의미 불분명)
  • 브라우저 히스토리, 앞으로/뒤로 가기 동작이 어색할 수 있음.
  • Lazy loading 불가능. 모든 컴포넌트가 초기 번들에 포함됨 → 성능 저하 우려.

사용 시기

  • 탭 전환, 다중 동시 뷰 렌더링.
  • SEO와 무관한 admin 페이지나 앱 내부 UI.

 

 


 

 

2. 라우트 분리 방식

// app-routing.module.ts
const routes: Routes = [
  { path: 'main/tab-one', component: TabOneComponent },
  { path: 'main/tab-two', component: TabTwoComponent },
];



<!-- main.component.html -->
<router-outlet></router-outlet>

 

 

장점

  • URL 구조가 명확하다. (/main/tab-one → 명시적 경로)
  • 브라우저 히스토리 지원, 북마크, 공유 등에서 유저 경험이 뛰어남.
  • Lazy loading, preloading 전략 사용 가능 → 성능 최적화에 유리.
  • SSR(서버 사이드 렌더링)과 SEO에 유리함.

단점

  • 컴포넌트가 완전히 갈아끼워지기 때문에 상태 유지가 어렵다.
  • UI 전환 속도가 느려질 수 있으며, 로딩 처리도 신경 써야 함.
  • 복잡한 탭 UI에서 URL 관리가 오히려 개발 비용을 증가시킬 수 있음.

사용 시기

  • 독립적인 페이지 역할을 하는 경우.
  • SEO, 접근성, 공유 등 URL 의미가 중요한 화면.
  • Lazy loading을 통한 성능 개선이 필요한 대규모 앱.

 

 


 

 

선택 기준 정리

상황 추천 방식 이유
탭 UI, 내부 상태 전환 컴포넌트 인클루전 빠른 전환과 상태 공유에 유리하며 라우트가 필요 없음
명확한 URL 필요 라우트 분리 URL만으로 어떤 화면인지 식별 가능함
공유 가능한 화면 라우트 분리 URL 복사/북마크/뒤로가기 등 지원이 자연스러움
Lazy loading 필요 라우트 분리 페이지 단위 로딩으로 성능 최적화 가능
빠른 전환, 작은 범위 UI 컴포넌트 인클루전 라우트 변경 없는 즉각적인 UI 렌더링이 가능함
SSR, SEO 고려 라우트 분리 각 화면이 독립된 경로를 가지기 때문에 크롤러 최적화에 유리

'개발 공부 > Angular' 카테고리의 다른 글

앵귤러 동적 라우팅(Dynamic Routing)  (0) 2025.05.31
RxJS 연산자 debounceTime, switchMap, mergeMap  (1) 2025.05.29
Angular computed()  (0) 2025.05.26
@HostListener  (0) 2025.05.19
Angular Directive  (0) 2025.05.17