Angular @defer ์์ ๊ฐ์ด๋ 2026: ์ ์ธ์ ์ง์ฐ ๋ก๋ฉ๊ณผ ๋ฉด์ ์ง๋ฌธ
Angular @defer ๋ธ๋ก์ ํ์ฉํ ์ ์ธ์ ์ง์ฐ ๋ก๋ฉ์ ์๋ ์๋ฆฌ, ํธ๋ฆฌ๊ฑฐ ์ ํ, ํ๋ฆฌํ์น ์ ๋ต, ์ ์ง์ ํ์ด๋๋ ์ด์ , ๋ฉด์ ์ง๋ฌธ์ ์์ธํ ๋ค๋ฃน๋๋ค.

Angular์ @defer ๋ธ๋ก์ ๋ผ์ฐํฐ ๊ธฐ๋ฐ ์ง์ฐ ๋ก๋ฉ์ผ๋ก๋ ํด๊ฒฐํ ์ ์์๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ ๋ณ๋์ ๋ผ์ฐํธ๋ก ์ฌ๊ตฌ์ฑํ์ง ์๊ณ ๋ ๊ฐ๋ณ ์ปดํฌ๋ํธ, ๋๋ ํฐ๋ธ, ํ์ดํ๋ฅผ ์จ๋๋งจ๋๋ก ๋ก๋ฉํ ์ ์์ต๋๋ค. Angular 17์์ ๋์
๋๊ณ Angular 22์์ ์์ ํ๋ @defer๋ ๋์ ์ํฌํธ, *ngIf ํ๋๊ทธ, webpack ์ค์ ์ ์กฐํฉํด์ผ ํ๋ ์์
์ ํ๋์ ์ ์ธ์ ํ
ํ๋ฆฟ ๋ธ๋ก์ผ๋ก ๋ณํํฉ๋๋ค.
@defer๋ ๋ํ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ณ๋์ JavaScript ์ฒญํฌ๋ก ๋ถํ ํ๊ณ , ํธ๋ฆฌ๊ฑฐ ์กฐ๊ฑด์ด ๋ฐ๋๋ ๋๋ง ๋ก๋ฉํ๋๋ก Angular ์ปดํ์ผ๋ฌ์ ์ง์ํฉ๋๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๊ธฐ์ ๋ค์ด๋ก๋ํ๋ JavaScript๊ฐ ์ค์ด๋ค์ด ์๋ ์ฝ๋ ๋ถํ ์ค์ ์์ด Largest Contentful Paint(LCP)์ Time to First Byte(TTFB)๊ฐ ๊ฐ์ ๋ฉ๋๋ค.
@defer์ ๋ด๋ถ ์๋ ๋ฉ์ปค๋์ฆ
Angular ์ปดํ์ผ๋ฌ๊ฐ @defer ๋ธ๋ก์ ๋ง๋๋ฉด, ๋ด๋ถ์ ๋ชจ๋ ์คํ ๋์ผ๋ก ์ปดํฌ๋ํธ, ๋๋ ํฐ๋ธ, ํ์ดํ๋ฅผ ๋ณ๋์ ์ฒญํฌ๋ก ์ถ์ถํฉ๋๋ค. ๋ฉ์ธ ๋ฒ๋ค์ ์ด๋ฌํ ์์กด์ฑ ์์ด ์ ๊ณต๋ฉ๋๋ค. ๋ฐํ์์ Angular๋ ํธ๋ฆฌ๊ฑฐ ์กฐ๊ฑด์ ํ๊ฐํ๊ณ ๋์ import() ํธ์ถ์ ํตํด ์ฒญํฌ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
์ด ๋ธ๋ก์ ๋ก๋ฉ ๋ผ์ดํ์ฌ์ดํด ๋์ ์ฌ์ฉ์์๊ฒ ํ์๋๋ ๋ด์ฉ์ ์ ์ดํ๋ 4๊ฐ์ ์๋ธ ๋ธ๋ก์ ์ง์ํฉ๋๋ค:
@defer (on viewport) {
<analytics-dashboard />
} @placeholder {
<div class="h-64 bg-muted animate-pulse"></div>
} @loading (minimum 200ms) {
<loading-spinner />
} @error {
<p>Failed to load the dashboard. Please refresh.</p>
}@placeholder๋ ํธ๋ฆฌ๊ฑฐ๊ฐ ๋ฐ๋๋๊ธฐ ์ ์ ๋ ๋๋ง๋ฉ๋๋ค. @loading์ ์ฒญํฌ๊ฐ ๋ค์ด๋ก๋๋๋ ๋์ ํ์๋๋ฉฐ, ๊น๋นก์์ ๋ฐฉ์งํ๊ธฐ ์ํ ์ ํ์ minimum ๊ธฐ๊ฐ์ ์ค์ ํ ์ ์์ต๋๋ค. @error๋ ๋คํธ์ํฌ ์ฅ์ ๋ ์ฒญํฌ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํฉ๋๋ค. @loading์ minimum ํ๋ผ๋ฏธํฐ๋ ์ฒญํฌ๊ฐ ์บ์์์ ๋น ๋ฅด๊ฒ ๋ก๋ฉ๋ ๋ ์คํผ๋๊ฐ ์ ๊น ํ์๋๋ ํ์์ ๋ฐฉ์งํฉ๋๋ค.
์ค์ํ ์ ์ฝ ์กฐ๊ฑด์ผ๋ก, @defer ๋ด๋ถ์ ๋ชจ๋ ์์กด์ฑ์ ์คํ ๋์ผ๋ก ์ด์ด์ผ ํฉ๋๋ค. NgModule์ ์ ์ธ๋ ๋น์คํ ๋์ผ๋ก ์ปดํฌ๋ํธ๋ ์ง์ฐ ๋ก๋ฉ์ด ๋ถ๊ฐ๋ฅํ๋ฉฐ, @defer ๋ํผ์ ๊ด๊ณ์์ด ์ฆ์ ๋ก๋ฉ๋ฉ๋๋ค.
ํธ๋ฆฌ๊ฑฐ ์ ํ: ์ปดํฌ๋ํธ ๋ก๋ฉ ์์ ์ ์ด
Angular๋ 7๊ฐ์ง ๋ด์ฅ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ ๊ณตํ๋ฉฐ, ๊ฐ๊ฐ ๋ค๋ฅธ ๋ก๋ฉ ์ ๋ต์ ๋์ํฉ๋๋ค. ์ฌ๋ฌ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ธ๋ฏธ์ฝ๋ก ์ผ๋ก ๊ฒฐํฉํ ์ ์์ผ๋ฉฐ OR ์กฐ๊ฑด์ผ๋ก ํ๊ฐ๋ฉ๋๋ค.
// ๋ธ๋ผ์ฐ์ ๊ฐ ์ ํด ์ํ์ผ ๋ ๋ก๋ฉ (๊ธฐ๋ณธ๊ฐ)
@defer {
<recommendation-engine />
}
// ์์๊ฐ ๋ทฐํฌํธ์ ๋ค์ด์ฌ ๋ ๋ก๋ฉ
@defer (on viewport) {
<customer-reviews [productId]="product.id" />
}
// ํด๋ฆญ ๋๋ ํค๋ค์ด ์ ๋ก๋ฉ
@defer (on interaction) {
<product-configurator />
} @placeholder {
<button>Configure this product</button>
}
// ๋ง์ฐ์ค ์ค๋ฒ ๋๋ ํฌ์ปค์ค ์ ๋ก๋ฉ
@defer (on hover) {
<quick-preview />
}
// 3์ด ํ ๋ก๋ฉ
@defer (on timer(3s)) {
<chat-widget />
}
// ์ด๊ธฐ ๋ ๋๋ง ์งํ ๋ก๋ฉ
@defer (on immediate) {
<notification-center />
}on viewport ํธ๋ฆฌ๊ฑฐ๋ ๋ด๋ถ์ ์ผ๋ก Intersection Observer API๋ฅผ ์ฌ์ฉํฉ๋๋ค. on idle ํธ๋ฆฌ๊ฑฐ๋ requestIdleCallback์ ์์ํ๋ฏ๋ก ํด๋ ์๋ ์ฝํ
์ธ ์ ๊ฐ์ฅ ์์ ํ ๊ธฐ๋ณธ๊ฐ์
๋๋ค. on timer ํธ๋ฆฌ๊ฑฐ๋ ๋ฐ๋ฆฌ์ด(500ms) ๋๋ ์ด(3s) ๋จ์๋ก ๊ธฐ๊ฐ์ ์ง์ ํ ์ ์์ต๋๋ค.
when ํธ๋ฆฌ๊ฑฐ๋ฅผ ํตํ ๋ฆฌ์กํฐ๋ธ ์กฐ๊ฑด
์ด๋ฒคํธ ๊ธฐ๋ฐ ํธ๋ฆฌ๊ฑฐ ์ธ์๋ when์ ์๊ทธ๋ ์ฝ๊ธฐ๋ฅผ ํฌํจํ ๋ชจ๋ boolean ํํ์์ ๋ฐ์๋ค์
๋๋ค:
export class DashboardComponent {
showAdvanced = signal(false);
}
// dashboard.component.html
@defer (when showAdvanced()) {
<advanced-analytics />
} @placeholder {
<button (click)="showAdvanced.set(true)">Show advanced analytics</button>
}on๊ณผ when์ ์กฐํฉ์ ์ ํจํฉ๋๋ค. Angular๋ ์ด๋ฅผ OR๋ก ์ฒ๋ฆฌํ๋ฉฐ, ์ด๋ ์กฐ๊ฑด์ด๋ ์ถฉ์กฑ๋๋ฉด ๋ธ๋ก์ด ๋ก๋ฉ๋ฉ๋๋ค.
ํ๋ฆฌํ์น: ๋ค์ด๋ก๋์ ํ์์ ๋ถ๋ฆฌ
ํ๋ฆฌํ์น๋ ์ฒญํฌ์ ๋ค์ด๋ก๋ ์์ ๊ณผ ์ปดํฌ๋ํธ์ ๋ ๋๋ง ์์ ์ ๋ถ๋ฆฌํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ํธ๋ฆฌ๊ฑฐ๋ฅผ ๋ฐ๋์ํค๊ธฐ ์ ์ JavaScript๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ์ ธ์ ์ฒด๊ฐ ์ง์ฐ ์๊ฐ์ ์ ๊ฑฐํฉ๋๋ค.
@defer (on interaction; prefetch on idle) {
<account-settings />
} @placeholder {
<button>Open settings</button>
}์ด ํจํด์์ ๋ธ๋ผ์ฐ์ ๋ ์ ํด ์๊ฐ ๋์ account-settings ์ฒญํฌ๋ฅผ ๋ค์ด๋ก๋ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ํด๋ฆญํ๋ฉด ์ฝ๋๊ฐ ์ด๋ฏธ ์ฌ์ฉ ๊ฐ๋ฅํ๋ฏ๋ก ์ปดํฌ๋ํธ๊ฐ ์ฆ์ ๋ ๋๋ง๋ฉ๋๋ค. ํ๋ฆฌํ์น๋ ๋ฉ์ธ on ์ ๊ณผ ๋์ผํ ํธ๋ฆฌ๊ฑฐ ์ ํ์ ์ง์ํฉ๋๋ค.
๋์๋ณด๋์์ ์ผ๋ฐ์ ์ธ ํจํด์ผ๋ก, ๋ฌด๊ฑฐ์ด ์ปดํฌ๋ํธ๋ฅผ ์ ํด ์ ํ๋ฆฌํ์นํ๊ณ ๋ทฐํฌํธ ์ง์ ์ ๋ ๋๋ง์ ์ง์ฐํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
@defer (on viewport; prefetch on idle) {
<chart-widget [data]="salesData()" />
} @placeholder (minimum 100ms) {
<div class="h-48 bg-muted rounded-none"></div>
}@placeholder์ minimum์ ์ฌ์ฉ์๊ฐ ๋น ๋ฅด๊ฒ ์คํฌ๋กคํ์ฌ ์ง์ฐ ์ปดํฌ๋ํธ๊ฐ ๊ฑฐ์ ์ฆ์ ๋ก๋ฉ๋ ๋ ๋ ์ด์์ ๊น๋นก์์ ๋ฐฉ์งํฉ๋๋ค.
Angular ๋ฉด์ ์ค๋น๊ฐ ๋์ จ๋์?
์ธํฐ๋ํฐ๋ธ ์๋ฎฌ๋ ์ดํฐ, flashcards, ๊ธฐ์ ํ ์คํธ๋ก ์ฐ์ตํ์ธ์.
@defer์ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง
์๋ฒ์์ @defer ๋ธ๋ก์ ๊ธฐ๋ณธ์ ์ผ๋ก @placeholder ์ฝํ
์ธ ๋ฅผ ๋ ๋๋งํฉ๋๋ค. ์ง์ฐ ์ปดํฌ๋ํธ๋ ์๋ฒ ์ฌ์ด๋์์ ๋ ๋๋ง๋์ง ์์ต๋๋ค. ์ด ๋์์ ์๋์ ์ธ ๊ฒ์ผ๋ก, ์ฒญํฌ ๋ค์ด๋ก๋๋ ๋ธ๋ผ์ฐ์ ์ปจํ
์คํธ์์๋ง ์๋ฏธ๊ฐ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
SEO์ ์ค์ํ ์ฝํ
์ธ ์ ๊ฒฝ์ฐ, @placeholder์๋ ์คํผ๋๋ง์ด ์๋ ์๋ฏธ ์๋ HTML์ด ํฌํจ๋์ด์ผ ํฉ๋๋ค:
@defer (on viewport) {
<comment-section [postId]="post.id" />
} @placeholder {
<section aria-label="Comments">
<h2>Comments</h2>
<p>Loading comments...</p>
</section>
}๊ฒ์ ์์ง์ SSR ์ ํ๋ ์ด์คํ๋ ์ฝํ ์ธ ๋ฅผ ์ธ๋ฑ์ฑํฉ๋๋ค. ์ค๋ช ์ ์ธ ํ๋ ์ด์คํ๋๋ฅผ ํตํด ํ์ด์ง์ ์๋งจํฑ ์์ ์ฑ์ด ์ ์ง๋ฉ๋๋ค.
์ ์ง์ ํ์ด๋๋ ์ด์ ๊ณผ @defer
Angular 19์์ ๊ฐ๋ฐ์ ํ๋ฆฌ๋ทฐ๋ก ๋์
๋ ์ ์ง์ ํ์ด๋๋ ์ด์
์ Angular 22์์ ํ๋ก๋์
์ค๋น ๊ธฐ๋ฅ์ผ๋ก ์์ ํ๋์์ต๋๋ค. ์ ์ง์ ํ์ด๋๋ ์ด์
์ @defer๋ฅผ hydrate ํธ๋ฆฌ๊ฑฐ๋ก ํ์ฅํ์ฌ, ์๋ฒ์์ ๋ ๋๋ง๋ ์ปดํฌ๋ํธ๊ฐ ํด๋ผ์ด์ธํธ์์ ์ธ์ ์ธํฐ๋ํฐ๋ธํ๊ฒ ๋๋์ง ์ ์ดํฉ๋๋ค.
@defer (hydrate on viewport) {
<product-gallery [images]="product.images" />
}
@defer (hydrate on interaction) {
<product-reviews [productId]="product.id" />
}ํ์ค @defer์ ๋ฌ๋ฆฌ, ์ ์ง์ ํ์ด๋๋ ์ด์
์ ์๋ฒ์์ ์์ ํ ์ปดํฌ๋ํธ HTML์ ๋ ๋๋งํฉ๋๋ค. ํด๋ผ์ด์ธํธ๋ ์์ ํ ๋งํฌ์
์ ์์ ํ์ง๋ง ํธ๋ฆฌ๊ฑฐ๊ฐ ๋ฐ๋๋ ๋๊น์ง ์ปดํฌ๋ํธ์ ํ์ด๋๋ ์ด์
์ ๊ฑด๋๋๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ธ๋ผ์ฐ์ ๋ ์์ ํ ํ์ด์ง๋ฅผ ์ฆ์ ๊ทธ๋ฆฌ์ง๋ง, JavaScript ์คํ์ ์ง์ฐ๋ฉ๋๋ค.
Angular ํ์ ์ฝํ ์ธ ๊ฐ ๋ง์ ํ์ด์ง์์ ์ ์ง์ ํ์ด๋๋ ์ด์ ์ ์ฌ์ฉํ ๊ฒฝ์ฐ LCP ์ ์๊ฐ ์ผ๊ด๋๊ฒ 40~50% ๊ฐ์ ๋๋ค๊ณ ๋ณด๊ณ ํ๊ณ ์์ต๋๋ค. Angular 22์ Angular DevTools๋ ์ปดํฌ๋ํธ ์ธ์คํํฐ์์ ํ์ด๋๋ ์ด์ ์ํ(๋๊ธฐ ์ค, ํ์ด๋๋ ์ด์ ์๋ฃ, ์ค๋ฅ)๋ฅผ ์ง์ ์๊ฐํํฉ๋๋ค.
์ค์ ํจํด๊ณผ ์ฑ๋ฅ ์ ๋ต
ํจํด 1: ๋ณต์์ ์ง์ฐ ํจ๋์ ๊ฐ์ง ๋์๋ณด๋
<div class="grid grid-cols-2 gap-4">
@defer (on viewport; prefetch on idle) {
<sales-chart />
} @placeholder {
<skeleton-card height="300px" />
}
@defer (on viewport; prefetch on idle) {
<user-activity-feed />
} @placeholder {
<skeleton-card height="300px" />
}
@defer (on interaction) {
<export-panel />
} @placeholder {
<button>Export data</button>
}
</div>๊ฐ ํจ๋์ ๋ ๋ฆฝ์ ์ผ๋ก ๋ก๋ฉ๋ฉ๋๋ค. ๋ด๋ณด๋ด๊ธฐ ํจ๋์ ์ฌ์ฉ์๊ฐ ๋ช ์์ ์ผ๋ก ์์ฒญํ ๋๊น์ง ๋ก๋ฉ๋์ง ์์ ์ํ๋ฅผ ์ ์งํ์ฌ, ๋ด๋ณด๋ด๊ธฐ๋ฅผ ์ฌ์ฉํ์ง ์๋ ์ฌ์ฉ์์ ์ฒญํฌ ๋ค์ด๋ก๋๋ฅผ ์ ์ฝํฉ๋๋ค.
ํจํด 2: ์๊ทธ๋์ ํ์ฉํ ์กฐ๊ฑด๋ถ ๊ธฐ๋ฅ ๋ก๋ฉ
export class EditorComponent {
user = inject(UserService).currentUser;
isPremium = computed(() => this.user()?.plan === 'premium');
}
// editor.component.html
@defer (when isPremium()) {
<ai-assistant />
} @placeholder {
<upgrade-banner />
}๋ฌด๋ฃ ์๊ธ์ ์ฌ์ฉ์๋ AI ์ด์์คํดํธ ์ฒญํฌ๋ฅผ ๋ค์ด๋ก๋ํ์ง ์์ต๋๋ค. ์ ๊ทธ๋ ์ด๋ ๋ฐฐ๋๋ ํ๋ ์ด์คํ๋์ ์ ํ ์ด์ง์ ๋ ๊ฐ์ง ์ญํ ์ ์ํํฉ๋๋ค.
ํํ ์ค์ ํผํ๊ธฐ
๋์ผํ ํธ๋ฆฌ๊ฑฐ๋ฅผ ๊ฐ์ง @defer ๋ธ๋ก์ ์ค์ฒฉํ๋ฉด ๋์์ ์ฒญํฌ๊ฐ ๋ค์ด๋ก๋๋ฉ๋๋ค. ์ค์ฒฉ๋ ๋ธ๋ก ๊ฐ์ ํธ๋ฆฌ๊ฑฐ๋ฅผ ๋ถ์ฐ์ํค๋ ๊ฒ์ด ๋ฐ๋์งํฉ๋๋ค:
// ํผํด์ผ ํ ์: ๋ ๋ค ์ ํด ์ ๋์ ๋ฐ๋
@defer {
@defer {
<nested-heavy-component />
}
}
// ๊ถ์ฅ: ์ธ๋ถ๋ ์ ํด, ๋ด๋ถ๋ ๋ทฐํฌํธ
@defer (on idle) {
<wrapper-component />
}
// wrapper-component ํ
ํ๋ฆฟ ๋ด๋ถ:
@defer (on viewport) {
<nested-heavy-component />
}๋ ๋ค๋ฅธ ์ค์๋ ํฌ๋ฆฌํฐ์ปฌ ๋ ๋๋ง ๊ฒฝ๋ก์ ์ด๋ฏธ ์กด์ฌํ๋ ์ปดํฌ๋ํธ์ @defer๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. ํด๋ ์์ ์ฝํ
์ธ ๋ฅผ ์ง์ฐ ๋ก๋ฉํ๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ ํ์ธํ
์ ์ ์ฒญํฌ๋ฅผ ๋ค์ด๋ก๋ํ๊ณ ์คํํด์ผ ํ๋ฏ๋ก LCP๊ฐ ์ฆ๊ฐํฉ๋๋ค. @defer๋ ํด๋ ์๋ ๋๋ ์ฌ์ฉ์๊ฐ ํธ๋ฆฌ๊ฑฐํ๋ ์ฝํ
์ธ ์๋ง ์ฌ์ฉํด์ผ ํฉ๋๋ค.
@defer vs ๋ผ์ฐํฐ ๊ธฐ๋ฐ ์ง์ฐ ๋ก๋ฉ
๋ผ์ฐํฐ ๊ธฐ๋ฐ ์ง์ฐ ๋ก๋ฉ๊ณผ @defer๋ ์ํธ ๋ณด์์ ์
๋๋ค. ๋ผ์ฐํฐ ์ง์ฐ ๋ก๋ฉ์ ๋ผ์ฐํธ ์์ค์์ ๋ถํ ํ์ฌ ์ ์ฒด ๊ธฐ๋ฅ ๋ชจ๋์ ์ง์ฐ์ํต๋๋ค. @defer๋ ํ
ํ๋ฆฟ ๋ด์์ ๋ถํ ํ์ฌ ๊ฐ๋ณ ์ปดํฌ๋ํธ๋ฅผ ์ง์ฐ์ํต๋๋ค.
| ๊ด์ | ๋ผ์ฐํฐ ์ง์ฐ ๋ก๋ฉ | @defer |
|------|-----------------|--------|
| ์ธ๋ถ์ฑ | ๋ผ์ฐํธ ์์ค | ์ปดํฌ๋ํธ ์์ค |
| ํธ๋ฆฌ๊ฑฐ | ๋ด๋น๊ฒ์ด์
์ด๋ฒคํธ | viewport, idle, interaction, hover, timer, ์กฐ๊ฑด |
| SSR ๋์ | ์์ ํ ์๋ฒ ๋ ๋๋ง | ์๋ฒ์์ ํ๋ ์ด์คํ๋ |
| ์คํ ๋์ผ๋ก ํ์ | ์๋์ค (NgModules ์ง์) | ์ (์คํ ๋์ผ๋ก ๋ง) |
| ํ๋ฆฌํ์น | preloadingStrategy | prefetch on ์ |
| ์ฌ์ฉ ์ฌ๋ก | ๊ธฐ๋ฅ ๋ชจ๋, ํ์ด์ง | ์์ ฏ, ํจ๋, ์กฐ๊ฑด๋ถ UI |
์ผ๋ฐ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์
์์๋ ๋ ๋ค ์ฌ์ฉํฉ๋๋ค: ์ต์์ ๊ธฐ๋ฅ ์์ญ์๋ ๋ผ์ฐํฐ ์ง์ฐ ๋ก๋ฉ์, ํด๋น ์์ญ ๋ด์ ๋ฌด๊ฑฐ์ด ์ปดํฌ๋ํธ์๋ @defer๋ฅผ ์ ์ฉํฉ๋๋ค.
Angular @defer ๋ฉด์ ์ง๋ฌธ
๊ธฐ์ ๋ฉด์ ์์ @defer๊ฐ Angular ์ฑ๋ฅ ์ ๋ต์ ํต์ฌ์ด ๋จ์ ๋ฐ๋ผ, ์ด ๊ธฐ๋ฅ์ ๋ํ ์ง๋ฌธ์ด ์ฆ๊ฐํ๊ณ ์์ต๋๋ค. ๋ค์์ Angular ๋ฉด์ ์ง๋ฌธ์์ ์์ฃผ ๋ฑ์ฅํ๋ ํจํด์
๋๋ค.
Q: ๋น์คํ ๋์ผ๋ก ์ปดํฌ๋ํธ๋ฅผ @defer ์์ ๋ฐฐ์นํ๋ฉด ์ด๋ป๊ฒ ๋ฉ๋๊น?
์ปดํฌ๋ํธ๋ @defer ๋ธ๋ก๊ณผ ๊ด๊ณ์์ด ์ฆ์ ๋ก๋ฉ๋ฉ๋๋ค. Angular ์ปดํ์ผ๋ฌ๋ NgModule์ ์ ์ธ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ณ๋ ์ฒญํฌ๋ก ์ถ์ถํ ์ ์์ต๋๋ค. ์ค๋ฅ๋ ๋ฐ์ํ์ง ์์ง๋ง, ์ต์ ํ๊ฐ ์กฐ์ฉํ ์คํจํฉ๋๋ค.
Q: SSR์์ @defer๋ ์ด๋ป๊ฒ ๋์ํฉ๋๊น?
์๋ฒ๋ @placeholder ์ฝํ
์ธ ๋ฅผ ๋ ๋๋งํฉ๋๋ค. ์ง์ฐ ์ปดํฌ๋ํธ๋ ์๋ฒ ์ฌ์ด๋์์ ๋ ๋๋ง๋์ง ์์ต๋๋ค. ํ์ด๋๋ ์ด์
์ ํธ๋ฆฌ๊ฑฐ๊ฐ ๋ฐ๋๋ ๋ ํด๋ผ์ด์ธํธ์์ ์ํ๋ฉ๋๋ค(์ ์ง์ ํ์ด๋๋ ์ด์
์ ๊ฒฝ์ฐ hydrate on ์ฌ์ฉ).
Q: @defer๋ OnPush ๋ณ๊ฒฝ ๊ฐ์ง์ ํจ๊ป ์ฌ์ฉํ ์ ์์ต๋๊น?
์ฌ์ฉํ ์ ์์ต๋๋ค. @defer๋ ํ
ํ๋ฆฟ ์์ค์ ๊ธฐ๋ฅ์ด๋ฉฐ ์ด๋ค ๋ณ๊ฒฝ ๊ฐ์ง ์ ๋ต๊ณผ๋ ํธํ๋ฉ๋๋ค. ์ง์ฐ ์ปดํฌ๋ํธ๋ ๋ก๋ฉ๋ ํ ์์ฒด ๋ณ๊ฒฝ ๊ฐ์ง ์ค์ ์ ๋ฐ๋ฆ
๋๋ค.
Q: on idle๊ณผ on immediate์ ์ฐจ์ด์ ์ ๋ฌด์์
๋๊น?
on idle์ requestIdleCallback์ ํตํด ๋ธ๋ผ์ฐ์ ๊ฐ ๋ชจ๋ ๋ณด๋ฅ ์ค์ธ ์์
์ ์๋ฃํ ๋๊น์ง ๋๊ธฐํฉ๋๋ค. on immediate๋ Angular๊ฐ ์ด๊ธฐ ๋ ๋๋ง ํจ์ค๋ฅผ ์๋ฃํ ์งํ, ์ ํด ์ํ๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ํธ๋ฆฌ๊ฑฐ๋ฉ๋๋ค. on immediate๋ ์ฒซ ๋ฒ์งธ ํ์ธํธ๋ฅผ ์ฐจ๋จํด์๋ ์ ๋์ง๋ง ๋นจ๋ฆฌ ๋ก๋ฉํด์ผ ํ๋ ์ปดํฌ๋ํธ์ ์ ํฉํฉ๋๋ค.
๋ ๋์ ๋ฒ์์ Angular ๋ฉด์ ์ค๋น์ ๋ํด์๋ Angular ๋ณ๊ฒฝ ๊ฐ์ง ๋ชจ๋๊ณผ Angular ์๊ทธ๋ ๋ชจ๋์ ์ฐธ๊ณ ํ ์ ์์ต๋๋ค.
์ฐ์ต์ ์์ํ์ธ์!
๋ฉด์ ์๋ฎฌ๋ ์ดํฐ์ ๊ธฐ์ ํ ์คํธ๋ก ์ง์์ ํ ์คํธํ์ธ์.
๊ฒฐ๋ก
@defer๋ ์คํ ๋์ผ๋ก ์ปดํฌ๋ํธ๋ฅผ ๋ณ๋์ ์ฒญํฌ๋ก ๋ถํ ํ์ฌ ๋ผ์ฐํธ ์ฌ๊ตฌ์ฑ ์์ด ์ด๊ธฐ ๋ฒ๋ค ํฌ๊ธฐ๋ฅผ ์ค์ ๋๋ค- 7๊ฐ์ง ํธ๋ฆฌ๊ฑฐ ์ ํ(
idle,viewport,interaction,hover,timer,immediate,when)์ด ์๋์ ๋ก๋ฉ๋ถํฐ ์ฌ์ฉ์ ์ฃผ๋ ๋ก๋ฉ๊น์ง ๋ชจ๋ ์ ๋ต์ ํฌ๊ดํฉ๋๋ค prefetch on์ ์ฒญํฌ ๋ค์ด๋ก๋์ ์ปดํฌ๋ํธ ๋ ๋๋ง์ ๋ถ๋ฆฌํ์ฌ, ์ฌ์ฉ์ ํธ๋ฆฌ๊ฑฐ ์ปดํฌ๋ํธ์ ์ฒด๊ฐ ์ง์ฐ ์๊ฐ์ ์ ๊ฑฐํฉ๋๋ค- ์ ์ง์ ํ์ด๋๋ ์ด์
(
hydrate on)์ ์๋ฒ์์ ์์ ํ HTML์ ๋ ๋๋งํ๋ฉด์ JavaScript ์คํ์ ํด๋ผ์ด์ธํธ๋ก ์ง์ฐ์์ผ ์ฝํ ์ธ ๊ฐ ๋ง์ ํ์ด์ง์์ 40~50%์ LCP ๊ฐ์ ์ ๋ฌ์ฑํฉ๋๋ค @placeholder์ฝํ ์ธ ๋ SSR ์ ๋ ๋๋ง๋๋ฏ๋ก, SEO๋ฅผ ์ํด ์๋งจํฑ์ ์ผ๋ก ์๋ฏธ ์๋ ๋ด์ฉ์ด์ด์ผ ํฉ๋๋ค@defer๋ ๋ผ์ฐํฐ ๊ธฐ๋ฐ ์ง์ฐ ๋ก๋ฉ์ ๋ณด์ํฉ๋๋ค: ๋ผ์ฐํธ๋ ๊ธฐ๋ฅ ์์ค ๋ถํ ์,@defer๋ ํ ํ๋ฆฟ ๋ด ์ปดํฌ๋ํธ ์์ค ๋ถํ ์ ์ฌ์ฉ๋ฉ๋๋ค- ๋น์คํ ๋์ผ๋ก ์ปดํฌ๋ํธ๋ ์ง์ฐ ๋ก๋ฉ์ด ๋ถ๊ฐ๋ฅํ๋ฉฐ ์๋ฌต์ ์ผ๋ก ์ฆ์ ๋ก๋ฉ๋ฉ๋๋ค
์ฐ์ต์ ์์ํ์ธ์!
๋ฉด์ ์๋ฎฌ๋ ์ดํฐ์ ๊ธฐ์ ํ ์คํธ๋ก ์ง์์ ํ ์คํธํ์ธ์.
ํ๊ทธ
๊ณต์
๊ด๋ จ ๊ธฐ์ฌ

Angular 19 ๋ฉด์ ์ง๋ฌธ: Signals, SSR๊ณผ ๋ฐ๋์ ์์์ผ ํ ๊ฐ๋
๊ฐ์ฅ ์์ฃผ ๋์ค๋ Angular 19 ๋ฉด์ ์ง๋ฌธ: Signals, ์ ์ง์ ํ์ด๋๋ ์ด์ , zoneless ๋ณ๊ฒฝ ๊ฐ์ง, ์๋ก์ด ๋ฆฌ์กํฐ๋ธ API. ์ฝ๋ ์์ ์ ๊ธฐ๋๋๋ ๋ต๋ณ๊น์ง ํจ๊ป ์ ๋ฆฌํฉ๋๋ค.

Angular 2026์ RxJS: ์ฐ์ฐ์, Subject, Signals ์ํธ ์ด์ฉ
Angular 2026์ RxJS: ์ค๋ฌด์์ ์ฐ์ด๋ ์ฐ์ฐ์, Subject, Signals ์ํธ ์ด์ฉ ํจํด์ ๊ฐ์ฅ ์์ฃผ ๋์ค๋ ๋ฉด์ ์ง๋ฌธ๊ณผ ํจ๊ป ์ตํ๋๋ค.

Angular 19 Zoneless: Zone.js ์์ด ๊ตฌํํ๋ ์ฑ๋ฅ๊ณผ ๋ณ๊ฒฝ ๊ฐ์ง
Angular์ zoneless ๋ณ๊ฒฝ ๊ฐ์ง๋ Zone.js๋ฅผ ์์ ํ ์ ๊ฑฐํ์ฌ ๋ ์์ ๋ฒ๋ค ํฌ๊ธฐ, ๋น ๋ฅธ ๋ ๋๋ง, ๊ทธ๋ฆฌ๊ณ ์๊ทธ๋์ ํตํ ๋ช ์์ ๋ฐ์์ฑ์ ์ ๊ณตํฉ๋๋ค. ์ด ์ฌ์ธต ๊ฐ์ด๋๋ Angular 19์ provideExperimentalZonelessChangeDetection๋ถํฐ Angular 20+ ์์ ํ API๊น์ง Zone.js์์ zoneless Angular๋ก์ ๋ง์ด๊ทธ๋ ์ด์ ๊ฒฝ๋ก๋ฅผ ๋ค๋ฃน๋๋ค.