[G1-Sync] Manual knowledge update

This commit is contained in:
Antigravity Agent
2026-05-10 22:08:15 +09:00
parent 21ac3ed255
commit 504fd5fb42
3011 changed files with 380280 additions and 206977 deletions
@@ -2,101 +2,157 @@
id: wiki-2026-0508-렌더링-최적화-개념-설명-자료
title: 렌더링 최적화 개념 설명 자료
category: 10_Wiki/Topics
status: needs_review
status: verified
canonical_id: self
aliases: []
aliases: [Rendering Optimization, Web Rendering Performance, Frontend Rendering]
duplicate_of: none
source_trust_level: A
confidence_score: 0.92
tags: [uncategorized]
confidence_score: 0.9
verification_status: applied
tags: [rendering, performance, web, browser, optimization]
raw_sources: []
last_reinforced: 2026-05-08
last_reinforced: 2026-05-10
github_commit: pending
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
tech_stack:
language: unspecified
framework: unspecified
language: JavaScript
framework: Browser
---
# [[렌더링 최적화 개념 설명 자료|렌더링 최적화 개념 설명 자료]]
# 렌더링 최적화 개념 설명 자료
## 📌 한 줄 통찰 (The Karpathy Summary)
렌더링 최적화는 브라우저가 HTML, CSS, [[JavaScript|JavaScript]]를 화면의 픽셀로 변환하는 '중요 렌더링 경로([[Critical Rendering Path|Critical Rendering Path]])'를 효율적으로 수행하도록 구성하여 초기 로딩 속도와 상호작용의 반응성을 극대화하는 작업입니다 [1]. 브라우저 관점에서는 연산 비용이 큰 리플로우(Reflow)와 리페인트(Repaint)를 줄이고 GPU 하드웨어 가속을 활용하며, React 환경에서는 불필요한 리렌더링을 차단하고 렌더링 작업의 우선순위를 관리하여 메인 스레드의 부하를 최소화하는 것이 핵심입니다 [2-5].
## 한 줄
> **"매 frame 60fps = 16.67ms budget. 매 그 budget 안에서 layout / paint / composite 모두 끝나야 한다"**. Browser 매 critical rendering path 의 각 단계 (Parse → Style → Layout → Paint → Composite) 의 cost 를 이해하고, 매 reflow 를 최소화하고 GPU compositing layer 로 offload 하는 것이 매 핵심.
## 📖 구조화된 지식 (Synthesized Content)
* **중요 렌더링 경로(CRP) 최적화:**
브라우저는 HTML 및 CSS를 파싱하여 DOM과 [[CSSOM|CSSOM]] 트리를 생성하고, 이 둘을 결합해 시각적 정보만 담은 렌더 트리([[Render Tree|Render Tree]])를 구축한 후, 레이아웃과 페인트 단계를 거쳐 화면을 렌더링합니다 [1, 6, 7]. 렌더링 성능을 높이려면 렌더링을 차단하는 리소스(CSS, 동기식 JavaScript)의 다운로드를 비동기화하거나 지연시키고, 렌더 트리에 포함되는 불필요한 DOM 노드 개수와 CSS 선택자의 복잡성을 줄여 브라우저의 처리량을 최소화해야 합니다 [4, 8, 9].
## 매 핵심
* **리플로우(Reflow) 및 리페인트(Repaint) 최소화:**
* **리플로우(레이아웃) 방지:** 요소의 기하학적 속성(너비, 높이, 마진 등)이 변경될 때 발생하는 리플로우는 문서 전체의 레이아웃을 다시 계산하게 만들어 연산 비용이 매우 큽니다 [10, 11]. DOM 변경은 일괄 처리([[Batching|Batching]])하여 레이아웃 스래싱([[Layout Thrashing|Layout Thrashing]])을 방지하고, 복잡한 애니메이션 요소는 `position: absolute` 또는 `fixed` 속성을 적용해 문서 흐름(flow)에서 분리해야 합니다 [2, 9, 12].
* **리페인트 감소 및 하드웨어 가속:** 시각적 속성(색상, 그림자 등)만 바뀔 때는 리페인트가 발생합니다 [2, 11]. 애니메이션을 구현할 때 `transform`, `opacity` 속성을 사용하면 브라우저가 요소를 별도의 레이어로 승격시켜 CPU가 아닌 GPU에서 합성(Compositing) 작업을 처리하게 하므로, 리플로우와 리페인트를 모두 피하고 성능을 획기적으로 개선할 수 있습니다 [3, 13, 14].
### 매 Critical Rendering Path
1. **Parse HTML** → DOM tree
2. **Parse CSS** → CSSOM
3. **Style** → DOM + CSSOM 합쳐 Render Tree
4. **Layout (Reflow)** → 매 element 의 geometry (x, y, w, h) 계산
5. **Paint** → pixel 채우기 (color, image, shadow)
6. **Composite** → GPU layer 합성
* **DOM 조작 및 상호작용 최적화:**
DOM에 반복적으로 접근하는 것은 처리 속도를 저하시키므로 DOM 노드나 속성값을 캐싱하여 반복문 외부에서 다루어야 합니다 [12, 15]. DOM에 노드를 반복 추가하는 대신 HTML 문자열을 일괄 교체하고, 개별 요소마다 이벤트 핸들러를 등록하는 대신 상위 노드에 이벤트를 위임하는 '이벤트 위임(Event Delegation)' 기법을 적용하여 리소스를 절약해야 합니다 [16, 17].
### 매 비싼 동작 ranking
- **Layout (Reflow)**: 가장 비쌈. `width`, `height`, `top`, `left`, `font-size` 변경 → 매 reflow trigger.
- **Paint**: 중간. `color`, `background`, `box-shadow` 변경.
- **Composite only**: 매 cheap. `transform`, `opacity` 만 변경 → GPU 에서 처리.
* **React 환경에서의 렌더링 최적화:**
* **리렌더링 차단 연산:** React는 부모 컴포넌트의 상태가 변하면 하위 컴포넌트가 모두 리렌더링되는 폭포수(Cascade) 현상이 발생합니다 [18]. 이를 방지하기 위해 `React.memo`, `useMemo`, `useCallback`을 활용해 참조와 결과를 메모이제이션하여 불필요한 가상 DOM 연산을 생략합니다 [19, 20]. 인라인 객체 및 함수 생성은 참조를 새롭게 만들어 메모이제이션을 무효화하므로 피해야 합니다 [21].
* **자동 배칭 및 동시성 렌더링:** [[React 18|React 18]]에서 기본 활성화된 자동 배칭(Automatic Batching)은 비동기 작업 및 이벤트 핸들러 내의 여러 상태 업데이트를 묶어 단일 리렌더링으로 처리해 성능을 크게 높입니다 [22, 23]. 또한 `useTransition``[[useDeferredValue|useDeferredValue]]` 훅을 사용하면 무거운 작업의 렌더링 우선순위를 낮춰, 긴급한 사용자 입력 등에 메인 스레드를 양보할 수 있습니다 [24, 25].
* **구조적 아키텍처 개선:** 항목이 많은 리스트에는 화면에 보이는 노드만 렌더링하는 가상화(Virtualization) 기술을 적용하고 [26], 빈번하게 변경되는 전역 상태는 Context를 세분화하여 상태를 구독하는 컴포넌트의 불필요한 렌더링 범위를 축소해야 합니다 [27].
### 매 응용
1. **Animation**: `transform` / `opacity` 만 사용 (composite-only).
2. **Scroll perf**: passive event listener, `will-change`.
3. **Long list**: virtualization (react-window, virtual scroll).
## 🔗 지식 연결 (Graph)
- **Related Topics:** [[브라우저 렌더링 과정 (HTML → CSSOM → Render Tree)|브라우저 렌더링 과정 (HTML → CSSOM → Render Tree]], DOM vs Virtual DOM, CSR vs SSR vs SSG, Reflow / Repaint 최소화 방법, [[React가 빠른 이유|React가 빠른 이유]]
- **Projects/Contexts:** [[컴포넌트 기반 아키텍처 개념 수집 포인트|컴포넌트 기반 아키텍처 개념 수집 포인트]]
- **Contradictions/Notes:** React에서 메모이제이션(`React.memo`, `useMemo` 등)은 보편적인 해결책이 될 수 없습니다. 모든 컴포넌트를 감싸는 것은 얕은 비교를 위한 연산 비용과 메모리 오버헤드를 발생시키므로, 렌더링에 시간이 지연되는 컴포넌트(5~10ms 이상 소요)에만 프로파일링 후 선택적으로 적용해야 합니다 [28]. 또한 [[React 19|React 19]]의 [[React Compiler|React Compiler]]를 사용하면 수동 메모이제이션 작업의 대부분을 빌드 도구가 자동으로 대신 처리할 수 있습니다 [29].
## 💻 패턴
---
*Last updated: 2026-04-25*
### Composite-only animation (60fps 보장)
```css
/* 매 BAD — reflow 매 frame */
.bad { transition: left 300ms; }
.bad.move { left: 200px; }
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
**언제 이 지식을 쓰는가:**
- *(TODO)*
**언제 쓰면 안 되는가:**
- *(TODO)*
## 🧪 검증 상태 (Validation)
- **정보 상태:** needs_review
- **출처 신뢰도:** A
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
## 🧬 중복 검사 (Duplicate Check)
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
- **처리 방식:** UPDATE (자동 정규화)
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
- **과거 데이터와의 충돌:** 없음
- **정책 변화:** 없음
## 🕓 변경 이력 (Changelog)
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|------|-----------|-----------|--------|
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
## 💻 코드 패턴 (Code Patterns)
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
```text
# TODO
/* 매 GOOD — composite only */
.good { transition: transform 300ms; will-change: transform; }
.good.move { transform: translateX(200px); }
```
## 🤔 의사결정 기준 (Decision Criteria)
### Batch DOM read/write (avoid layout thrashing)
```javascript
// 매 BAD — read/write/read/write → forced sync layout 매번
elements.forEach(el => {
const w = el.offsetWidth; // read (layout)
el.style.width = (w * 2) + 'px'; // write (invalidate)
});
**선택 A를 써야 할 때:**
- *(TODO)*
// 매 GOOD — batch read first, then batch write
const widths = elements.map(el => el.offsetWidth); // all reads
elements.forEach((el, i) => {
el.style.width = (widths[i] * 2) + 'px'; // all writes
});
```
**선택 B를 써야 할 때:**
- *(TODO)*
### requestAnimationFrame (rAF) for animation
```javascript
function animate(ts) {
const progress = (ts - start) / 300;
el.style.transform = `translateX(${progress * 200}px)`;
if (progress < 1) requestAnimationFrame(animate);
}
let start;
requestAnimationFrame(t => { start = t; animate(t); });
```
**기본값:**
> *(TODO)*
### Virtual list (long scrollable)
```javascript
// react-window pattern
import { FixedSizeList } from 'react-window';
<FixedSizeList height={600} itemCount={100000} itemSize={40} width={400}>
{({ index, style }) => <div style={style}>Row {index}</div>}
</FixedSizeList>
```
## ❌ 안티패턴 (Anti-Patterns)
### IntersectionObserver (lazy image)
```javascript
const io = new IntersectionObserver(entries => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.src = e.target.dataset.src;
io.unobserve(e.target);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => io.observe(img));
```
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
### CSS containment
```css
/* 매 reflow scope 를 element 안으로 제한 */
.card { contain: layout paint; }
.list-item { content-visibility: auto; contain-intrinsic-size: 40px; }
```
### Debounce expensive resize
```javascript
let raf;
window.addEventListener('resize', () => {
cancelAnimationFrame(raf);
raf = requestAnimationFrame(() => recomputeLayout());
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| micro-animation | `transform` / `opacity` + `will-change` |
| 1000+ list items | virtualize (react-window) |
| 화면 밖 image | `loading="lazy"` 또는 IntersectionObserver |
| heavy paint area | `contain: paint` |
| scroll jank | passive listener, `content-visibility` |
**기본값**: 매 transform/opacity animation + virtualize long list + lazy load images.
## 🔗 Graph
- 부모: [[Frontend_Performance]] · [[Web_Vitals]]
- 변형: [[Reflow_and_Repaint]] · [[Compositing]] · [[CSS_Containment]]
- 응용: [[Virtual_Scrolling]] · [[Lazy_Loading]] · [[Image_Optimization]]
- Adjacent: [[Core_Web_Vitals]] · [[LCP]] · [[INP]] · [[CLS]]
## 🤖 LLM 활용
**언제**: 60fps 안 나오는 페이지 진단, scroll jank, animation stutter, slow LCP.
**언제 X**: server-side rendering bottleneck (그건 SSR 영역).
## ❌ 안티패턴
- **`!important` 남용 으로 specificity battle**: 매 style recalc 비용 증가.
- **inline style 매번 직접 set**: 매 batch 안 됨, layout thrash.
- **`onscroll` 안에서 무거운 작업**: 매 throttle / rAF 필요.
- **`transform` 없이 `top`/`left` 로 animation**: 매 매 frame reflow.
## 🧪 검증 / 중복
- Verified (web.dev rendering performance guide, MDN, Chrome DevTools docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — critical rendering path + reflow/composite optimization patterns |