[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -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 |
|
||||
|
||||
Reference in New Issue
Block a user