# [[Layout Thrashing]] ## πŸ“Œ[[ brief]] Summary λ ˆμ΄μ•„μ›ƒ μŠ€λž˜μ‹±(Layout Thrashing)은 λΈŒλΌμš°μ €κ°€ νŽ˜μ΄μ§€μ˜ ꡬ쑰λ₯Ό λ‹€μ‹œ 계산해야 ν•˜λŠ” λ¦¬ν”Œλ‘œμš°(Reflow)와 리페인트(Repaint)λ₯Ό κ³Όλ„ν•˜κ²Œ λ°˜λ³΅ν•  λ•Œ λ°œμƒν•˜λŠ” μ„±λŠ₯ 병λͺ© ν˜„μƒμž…λ‹ˆλ‹€ [1, 2]. 주둜 μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ DOM을 읽고 μ“°λŠ” μž‘μ—…μ„ 쒁은 루프 μ•ˆμ—μ„œ λ²ˆκ°ˆμ•„ μˆ˜ν–‰ν•˜κ±°λ‚˜ λ ˆμ΄μ•„μ›ƒμ— 큰 영ν–₯을 λ―ΈμΉ˜λŠ” CSS 속성을 μ• λ‹ˆλ©”μ΄μ…˜ν™”ν•  λ•Œ μœ λ°œλ©λ‹ˆλ‹€ [1, 2]. 이 ν˜„μƒμ€ ν”„λ ˆμž„ 속도λ₯Ό μ‹¬κ°ν•˜κ²Œ μ €ν•˜μ‹œν‚€κ³  μ• λ‹ˆλ©”μ΄μ…˜μ„ 끊기게 λ§Œλ“€μ–΄ μ „λ°˜μ μΈ μ‚¬μš©μž κ²½ν—˜μ„ ν›Όμ†ν•©λ‹ˆλ‹€ [1, 2]. ## πŸ“– Core Content **λ°œμƒ 원인** * **DOM 읽기/μ“°κΈ°μ˜ 반볡**: μžλ°”μŠ€ν¬λ¦½νŠΈ μŠ€ν¬λ¦½νŠΈκ°€ 쒁은 루프 λ‚΄μ—μ„œ DOM 속성에 λŒ€ν•œ 읽기와 μ“°κΈ°λ₯Ό λ²ˆκ°ˆμ•„ μˆ˜ν–‰ν•  λ•Œ ν”νžˆ λ°œμƒν•©λ‹ˆλ‹€ [2, 3]. 예λ₯Ό λ“€μ–΄ `offsetWidth`λ‚˜ `offsetHeight` 같은 크기 κ΄€λ ¨ 속성을 읽을 λ•Œ, λΈŒλΌμš°μ €λŠ” μ •ν™•ν•œ 치수λ₯Ό μ œκ³΅ν•˜κΈ° μœ„ν•΄ λ‚΄λΆ€ λ ˆμ΄μ•„μ›ƒ 큐(Queue)λ₯Ό κ°•μ œλ‘œ λΉ„μš°κ³  동기적 λ¦¬ν”Œλ‘œμš°(Synchronous reflow)λ₯Ό μˆ˜ν–‰ν•΄μ•Ό ν•˜λ―€λ‘œ ν”„λ ˆμž„ 속도에 μ•…μ˜ν–₯을 λ―ΈμΉ©λ‹ˆλ‹€ [2]. * **무거운 λ ˆμ΄μ•„μ›ƒ 속성 λ³€κ²½**: `width`, `height`, `margin`, `padding`, `left/top/right/bottom`κ³Ό 같이 κΈ°ν•˜ν•™μ  ν˜•νƒœλ‚˜ λ ˆμ΄μ•„μ›ƒμ— 직접적인 영ν–₯을 μ£ΌλŠ” 속성을 μ• λ‹ˆλ©”μ΄μ…˜ μ²˜λ¦¬ν•˜λ©΄ λΈŒλΌμš°μ €κ°€ λ ˆμ΄μ•„μ›ƒμ„ μ§€μ†μ μœΌλ‘œ μž¬κ³„μ‚°ν•˜κ²Œ λ˜μ–΄ λ ˆμ΄μ•„μ›ƒ μŠ€λž˜μ‹±μ„ μœ λ°œν•©λ‹ˆλ‹€ [1, 4, 5]. **μ΅œμ ν™” 및 ν•΄κ²° 방법** * **DOM 읽기와 μ“°κΈ° 뢄리**: λ ˆμ΄μ•„μ›ƒ μŠ€λž˜μ‹±μ„ λ°©μ§€ν•˜κΈ° μœ„ν•΄μ„œλŠ” DOM 값을 μ½λŠ” μž‘μ—…(Read)κ³Ό μ“°λŠ” μž‘μ—…(Write)을 μ—„κ²©νžˆ λΆ„λ¦¬ν•˜μ—¬ μˆ˜ν–‰ν•΄μ•Ό ν•©λ‹ˆλ‹€ [3]. * **DOM λ³€κ²½ 일괄 처리([[Batching]])**: λ‹€μˆ˜μ˜ DOM 변경을 ν•œ λ²ˆμ— λ¬Άμ–΄ μ²˜λ¦¬ν•˜λ©΄ λ¦¬ν”Œλ‘œμš°μ™€ 리페인트λ₯Ό 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€ [2, 6]. `classList.add()`λ‚˜ `cssText`λ₯Ό μ‚¬μš©ν•˜μ—¬ 단 ν•œ 번의 λ Œλ”λ§ 주기만 μœ λ°œν•˜κ±°λ‚˜ `innerHTML`을 μ‚¬μš©ν•˜μ—¬ μ—¬λŸ¬ μš”μ†Œλ₯Ό λ™μ‹œμ— μ—…λ°μ΄νŠΈν•  수 μžˆμŠ΅λ‹ˆλ‹€ [2, 6]. * **가상 DOM ν™œμš©**: μƒˆλ‘œμš΄ μš”μ†Œλ₯Ό 라이브 DOM에 직접 μΆ”κ°€ν•˜κΈ° 전에 `DocumentFragment`λ₯Ό ν™œμš©ν•˜μ—¬ μΆ”κ°€ν•˜κ±°λ‚˜, λ…Έλ“œλ₯Ό λ³΅μ œν•˜μ—¬ λ³€κ²½ν•œ ν›„ 원본과 κ΅μ²΄ν•˜λŠ” 방식을 μ“°λ©΄ μš”μ†Œλ‹Ή ν•œ λ²ˆμ”© 일어날 λ¦¬ν”Œλ‘œμš°λ₯Ό 단 ν•œ 번으둜 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€ [2, 6, 7]. * **μ• λ‹ˆλ©”μ΄μ…˜ 속성 λŒ€μ²΄**: μ• λ‹ˆλ©”μ΄μ…˜μ„ κ΅¬ν˜„ν•  λ•ŒλŠ” λ ˆμ΄μ•„μ›ƒμ„ λ³€κ²½ν•˜λŠ” 속성 λŒ€μ‹  GPU κ°€μ†μ˜ 이점을 얻을 수 μžˆλŠ” `transform`κ³Ό `opacity` 속성을 μ‚¬μš©ν•˜μ—¬ λ¦¬ν”Œλ‘œμš° λ°œμƒμ„ ν”Όν•΄μ•Ό ν•©λ‹ˆλ‹€ [5, 8, 9]. λ˜ν•œ μžλ°”μŠ€ν¬λ¦½νŠΈ 기반 μ• λ‹ˆλ©”μ΄μ…˜μ—μ„œλŠ” `requestAnimationFrame`을 μ‚¬μš©ν•˜μ—¬ λΈŒλΌμš°μ €μ˜ λ„€μ΄ν‹°λΈŒ 리페인트 주기와 λ™κΈ°ν™”μ‹œν‚΄μœΌλ‘œμ¨ λŠκΉ€ μ—†λŠ” λͺ¨μ…˜μ„ κ΅¬ν˜„ν•΄μ•Ό ν•©λ‹ˆλ‹€ [2, 3, 6]. * **μŠ€νƒ€μΌ 적용 방식 μ΅œμ ν™”**: μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ 직접 인라인 μŠ€νƒ€μΌμ„ μ‘°μž‘ν•˜κΈ°λ³΄λ‹€λŠ” CSS 클래슀λ₯Ό μΆ”κ°€/μ œκ±°ν•˜λŠ” 방식을 μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€ [6]. λ Œλ”λ§ 속도λ₯Ό λŠ¦μΆ”λŠ” 깊고 λ³΅μž‘ν•œ CSS μ„ νƒμžμ˜ μ‚¬μš©μ„ ν”Όν•˜κ³ , 자주 변경될 μš”μ†Œμ—λŠ” `will-change` 속성을 톡해 λΈŒλΌμš°μ €κ°€ 미리 λ Œλ”λ§μ„ μ΅œμ ν™”ν•  수 μžˆλŠ” 힌트λ₯Ό μ œκ³΅ν•˜λŠ” 것도 λ°©λ²•μž…λ‹ˆλ‹€ [3, 6, 10]. ## πŸ”— Knowledge Connections - **Related Topics:** Reflow, Repaint, [[CSS Animations]], [[Performance Optimization]] - **Projects/Contexts:** [[Frontend]] [[Architecture]], [[μ‹€λ¬΄μ—μ„œ CSS κ΄€λ¦¬ν•˜λŠ” 방법]] - **Contradictions/Notes:** `will-change` 속성은 λΈŒλΌμš°μ €κ°€ λ³€κ²½ 사항에 미리 λŒ€λΉ„ν•˜κ²Œ ν•΄μ£Όμ–΄ μ„±λŠ₯을 ν–₯상할 수 μžˆμ§€λ§Œ, λ„ˆλ¬΄ λ§Žμ€ μš”μ†Œμ— λΆˆν•„μš”ν•˜κ²Œ μ μš©ν•  경우 였히렀 λΈŒλΌμš°μ € μžμ›μ„ λ‚­λΉ„ν•˜μ—¬ μ„±λŠ₯ 문제λ₯Ό μΌμœΌν‚¬ 수 μžˆμœΌλ―€λ‘œ μ‹ μ€‘ν•˜κ²Œ μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€ [10]. --- *Last updated: 2026-04-26*