01. ๐ŸŒ ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง๊ณผ CRP์˜ ์‹ฌ์ธต ์›๋ฆฌ

2026๋…„ 3์›” 5์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

๋ธŒ๋ผ์šฐ์ €๊ฐ€ HTML์„ ํ™”๋ฉด์— ๊ทธ๋ฆฌ๋Š” ์ „ ๊ณผ์ •์„ ๋งˆ์Šคํ„ฐํ•˜๊ณ , ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ๊ทผ๋ณธ์ธ CRP๋ฅผ ์ •๋ณตํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ด ๋ฉด์ ‘ ํ•ญ๋ชฉ์˜ ๋ชฉํ‘œ

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 20๋ถ„ (ํ•ต์‹ฌ ์š”์•ฝ: 10๋ถ„)

๐Ÿ—บ๏ธ ์ด ์ฑ•ํ„ฐ์˜ ํ๋ฆ„
[๊ฐœ๋… ์‚ฌ์ „] โ†’ [์งˆ๋ฌธ 1: ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ] โ†’ [์งˆ๋ฌธ 2: Reflow/Repaint ์ตœ์ ํ™”] โ†’ [์งˆ๋ฌธ 3: ์• ๋‹ˆ๋ฉ”์ด์…˜ ์„ฑ๋Šฅ]

๐ŸŽฏ ์ด ์ฑ•ํ„ฐ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

  • ๋ธŒ๋ผ์šฐ์ €์˜ 6๋‹จ๊ณ„ ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์„ ์™„๋ฒฝํžˆ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ ˆ์ด์•„์›ƒ ์Šค๋ž˜์‹ฑ(Layout Thrashing)์˜ ์›์ธ๊ณผ ํ•ด๊ฒฐ์ฑ…์„ ์ œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • GPU ๊ฐ€์†์ด ์ผ์–ด๋‚˜๋Š” ์กฐ๊ฑด๊ณผ ๊ทธ ๊ธฐํšŒ๋น„์šฉ์„ ๋…ผ๋ฆฌ์ ์œผ๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“š ํ•ต์‹ฌ ๊ฐœ๋… ์‚ฌ์ „ (Concept Glossary)

์งˆ๋ฌธ์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „, ์ด ์ฑ•ํ„ฐ๋ฅผ ๊ด€ํ†ตํ•˜๋Š” ํ•ต์‹ฌ ์šฉ์–ด๋“ค์„ ๋จผ์ € ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

1. CRP (Critical Rendering Path)

๋ธŒ๋ผ์šฐ์ €๊ฐ€ HTML, CSS, JavaScript๋ฅผ ์ˆ˜์‹ ํ•˜์—ฌ ์‹ค์ œ ํ”ฝ์…€๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ๊นŒ์ง€์˜ ์ผ๋ จ์˜ ๋‹จ๊ณ„๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ๋กœ๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๊ฒƒ์ด ๊ณง ์›น ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ์‹œ์ž‘์ž…๋‹ˆ๋‹ค.

2. ๋ ˆ์ด์•„์›ƒ ์Šค๋ž˜์‹ฑ (Layout Thrashing)

JavaScript ์ฝ”๋“œ๊ฐ€ DOM์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์ฆ‰์‹œ ๊ธฐํ•˜ํ•™์  ์ •๋ณด(offsetWidth, scrollTop ๋“ฑ)๋ฅผ ์ฝ์œผ๋ ค ํ•  ๋•Œ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ตœ์ ํ™”๋ฅผ ํฌ๊ธฐํ•˜๊ณ  ๊ฐ•์ œ๋กœ ๋ ˆ์ด์•„์›ƒ์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ํ˜„์ƒ์ž…๋‹ˆ๋‹ค. ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•˜๋Š” ์ฃผ๋ฒ”์ž…๋‹ˆ๋‹ค.

3. ์ปดํฌ์ง€ํŒ… (Compositing)

ํ™”๋ฉด์˜ ๊ฐ ๋ถ€๋ถ„์„ ๋ณ„๋„์˜ ๋ ˆ์ด์–ด๋กœ ๋‚˜๋ˆ„์–ด ๊ทธ๋ฆฐ ๋’ค, ๋งˆ์ง€๋ง‰์— ํ•˜๋‚˜๋กœ ํ•ฉ์„ฑํ•˜๋Š” ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค. transform, opacity ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ ˆ์ด์•„์›ƒ๊ณผ ํŽ˜์ธํŠธ ๋‹จ๊ณ„๋ฅผ ๊ฑด๋„ˆ๋›ฐ๊ณ  GPU์—์„œ ๋ฐ”๋กœ ํ•ฉ์„ฑํ•  ์ˆ˜ ์žˆ์–ด ๋งค์šฐ ๋น ๋ฆ…๋‹ˆ๋‹ค.


๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

  • ๐Ÿฃ ์˜์ฒ  ( ์‹ ์ž… ): "์˜ํ˜ธ ๋‹˜! ์ด๋ฒˆ์— '์˜์ˆ˜๋„ค ๊ฒŒ์‹œํŒ' ๋ฌดํ•œ ์Šคํฌ๋กค์„ ๊ตฌํ˜„ํ–ˆ๋Š”๋ฐ, ์Šคํฌ๋กคํ•  ๋•Œ๋งˆ๋‹ค ํ™”๋ฉด์ด ๋š๋š ๋Š๊ฒจ์š”. ๋ถ„๋ช… ์‚ฌ์–‘ ์ข‹์€ ๋งฅ๋ถ์ธ๋ฐ ์™œ ์ด๋Ÿด๊นŒ์š”? ๐Ÿ˜ญ"
  • ๐Ÿฆ ์˜ํ˜ธ ( ๋ฆฌ๋“œ ): "์˜์ฒ  ๋‹˜, ํ™”๋ฉด์ด ๋Š๊ธด๋‹ค๋Š” ๊ฑด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ดˆ๋‹น 60ํ”„๋ ˆ์ž„์„ ๊ทธ๋ ค๋‚ด๋Š” '๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ' ์–ด๋”˜๊ฐ€์—์„œ ๋ณ‘๋ชฉ์ด ์ƒ๊ฒผ๋‹ค๋Š” ๋œป์ด์—์š”. ๋‹จ์ˆœํžˆ ์ฝ”๋“œ๊ฐ€ ๋Œ์•„๊ฐ€๋Š” ๊ฑธ ๋„˜์–ด, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์–ด๋–ป๊ฒŒ ์ผํ•˜๋Š”์ง€ ์•Œ๋ฉด ํ•ด๊ฒฐ์ฑ…์€ ๋ฐ”๋กœ ๋‚˜์˜ต๋‹ˆ๋‹ค. ์ž, ๋ฉด์ ‘์ด๋ผ ์ƒ๊ฐํ•˜๊ณ  ๋Œ€๋‹ตํ•ด ๋ณด์„ธ์š”."

Q1. ๋ธŒ๋ผ์šฐ์ €์˜ ๋ Œ๋”๋ง ๊ณผ์ •์„ ๋‹จ๊ณ„๋ณ„๋กœ ์„ค๋ช…ํ•ด ๋ณด์„ธ์š”.

๐ŸŽฏ ์ถœ์ œ ์˜๋„

์ง€์›์ž๊ฐ€ ๋‹จ์ˆœํžˆ ํ”„๋ ˆ์ž„์›Œํฌ ์‚ฌ์šฉ๋ฒ•์„ ๋„˜์–ด, ์›น์ด ๋™์ž‘ํ•˜๋Š” ํ•˜๋ถ€ ํ™˜๊ฒฝ(Browser)์˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋Šฅ๋ ฅ์„ ํŒ๋‹จํ•˜๋Š” ๊ฐ€์žฅ ๊ธฐ์ดˆ์ ์ธ ์ฒ™๋„์ž…๋‹ˆ๋‹ค.

๐Ÿฃ ์˜์ฒ ์ด์˜ Naive ๊ตฌํ˜„ (Bad Case)

์˜์ฒ ์ด๋Š” ๊ฒŒ์‹œ๋ฌผ์„ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์ŠคํŠธ ์ „์ฒด๋ฅผ ๋‹ค์‹œ ๊ทธ๋ฆฌ๋Š” ๋น„ํšจ์œจ์ ์ธ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

// ๐Ÿฃ ์˜์ฒ : "๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ์—ˆ์œผ๋‹ˆ ๊น”๋”ํ•˜๊ฒŒ ์ƒˆ๋กœ ๊ทธ๋ ค์•ผ์ง€!"
function updateBoardList(posts) {
    const list = document.getElementById('board-list');
    list.innerHTML = ''; // โš ๏ธ ๊ธฐ์กด DOM์„ ํ†ต์งธ๋กœ ๋‚ ๋ฆฌ๊ณ  ์ƒˆ๋กœ ์ƒ์„ฑ (๋น„์‹ผ ๋น„์šฉ)
    
    posts.forEach(post => {
        list.innerHTML += `<li>${post.title}</li>`; // โš ๏ธ ๋งค ๋ฃจํ”„๋งˆ๋‹ค ๋ฌธ์ž์—ด ํŒŒ์‹ฑ & DOM ํŠธ๋ฆฌ ์žฌ๊ตฌ์„ฑ
    });
}

๐Ÿฆ ์˜ํ˜ธ์˜ ํŒฉํญ ์กฐ์–ธ
"์˜์ฒ  ๋‹˜, innerHTML +=๋Š” ๋งค๋ฒˆ HTML ์ „์ฒด๋ฅผ ๋ฌธ์ž์—ด๋กœ ํŒŒ์‹ฑํ•˜๊ณ  DOM ํŠธ๋ฆฌ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“œ๋Š” ์ตœ์•…์˜ ๋ฐฉ์‹์ด์—์š”. ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ทธ๋•Œ๋งˆ๋‹ค ํŒŒ์‹ฑ-์Šคํƒ€์ผ-๋ ˆ์ด์•„์›ƒ-ํŽ˜์ธํŠธ๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋„ˆ๋ฌด ๊ดด๋กญํžˆ์ง€ ๋งˆ์„ธ์š”."

๐Ÿฆ ์˜ํ˜ธ์˜ ์•„ํ‚คํ…์ฒ˜ ๊ฐ€์ด๋“œ (Good Case)

์˜ํ˜ธ ๋ฆฌ๋“œ๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํšจ์œจ์ ์œผ๋กœ ์ผํ•  ์ˆ˜ ์žˆ๋„๋ก DocumentFragment์™€ ์ตœ์ ํ™”๋œ API๋ฅผ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

// ๐Ÿฆ ์˜ํ˜ธ: "๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ '์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ'๋งŒ ํ•œ ๋ฒˆ์— ๋˜์ ธ์ฃผ์„ธ์š”."
function updateBoardList(posts) {
    const list = document.getElementById('board-list');
    const fragment = document.createDocumentFragment(); // ๋ฉ”๋ชจ๋ฆฌ์ƒ ๊ฐ€์ƒ ์ปจํ…Œ์ด๋„ˆ
 
    posts.forEach(post => {
        const li = document.createElement('li');
        li.textContent = post.title; // ํ…์ŠคํŠธ๋งŒ ์•ˆ์ „ํ•˜๊ฒŒ ์ฃผ์ž…
        fragment.appendChild(li);
    });
 
    list.replaceChildren(fragment); // ๋‹จ ํ•œ ๋ฒˆ์˜ DOM ์กฐ์ž‘์œผ๋กœ ๋!
}

๐Ÿ“Š ๋ ˆ๋ฒจ๋ณ„ ๋‹ต๋ณ€ ๊ฐ€์ด๋“œ (Self-Check)

  • Level 1 (Junior): "HTML๋กœ DOM ํŠธ๋ฆฌ, CSS๋กœ CSSOM ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด ๋‘˜์„ ํ•ฉ์ณ Render Tree๋ฅผ ๋งŒ๋“ค๊ณ , ์š”์†Œ์˜ ํฌ๊ธฐ์™€ ์œ„์น˜๋ฅผ ์ •ํ•˜๋Š” Layout, ์ƒ‰์„ ์น ํ•˜๋Š” Paint ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ ํ™”๋ฉด์— ๋ณด์—ฌ์ค๋‹ˆ๋‹ค."
  • Level 2 (Senior): "Render Tree์—๋Š” display: none ๊ฐ™์€ ์š”์†Œ๋Š” ํฌํ•จ๋˜์ง€ ์•Š์Œ์„ ์–ธ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. Layout ์ดํ›„ Paint ๋‹จ๊ณ„์—์„œ ๋ ˆ์ด์–ด๊ฐ€ ๋‚˜๋ˆ„์–ด์ง€๋ฉฐ, ๋งˆ์ง€๋ง‰์— Composite ๋‹จ๊ณ„์—์„œ ๋ ˆ์ด์–ด๊ฐ€ ํ•ฉ์„ฑ๋œ๋‹ค๋Š” ์ ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. transform ์†์„ฑ์ด ์™œ ๋น ๋ฅธ์ง€ ํŒŒ์ดํ”„๋ผ์ธ ๊ด€์ ์—์„œ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค."
  • Level 3 (Specialist): "ํ•˜๋“œ์›จ์–ด ๊ฐ€์†(GPU)์ด ์ผ์–ด๋‚˜๋Š” ํŠน์ • ์กฐ๊ฑด(Will-change ๋“ฑ)์„ ์„ค๋ช…ํ•˜๊ณ , ๋ฌด๋ถ„๋ณ„ํ•œ ๋ ˆ์ด์–ด ์ƒ์„ฑ์ด ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ(Memory Bloat)์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๋ฅผ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ์—”์ง„(V8, Blink ๋“ฑ)์˜ ์ตœ์ ํ™” ์ „๋žต๊ณผ ์—ฐ๊ด€ ์ง€์–ด ๋‹ต๋ณ€ํ•ฉ๋‹ˆ๋‹ค."

Q2. ๋ฆฌํ”Œ๋กœ์šฐ(Reflow)์™€ ๋ฆฌํŽ˜์ธํŠธ(Repaint)์˜ ์ฐจ์ด์™€ ์ตœ์ ํ™” ์ „๋žต์„ ์„ค๋ช…ํ•ด ๋ณด์„ธ์š”.

๐ŸŽฏ ์ถœ์ œ ์˜๋„

๋‹จ์ˆœํžˆ ์šฉ์–ด๋ฅผ ์•„๋Š”์ง€ ๋ฌป๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, DOM ์กฐ์ž‘์ด ๋ธŒ๋ผ์šฐ์ € ๋‚ด๋ถ€ ํ”„๋กœ์„ธ์Šค์— ๋ฏธ์น˜๋Š” '๋น„์šฉ(Cost)'์„ ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ์ตœ์†Œํ™”ํ•˜๋Š” ์ฝ”๋”ฉ ์Šต๊ด€์„ ๊ฐ–์ถ”๊ณ  ์žˆ๋Š”์ง€ ํ‰๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿฃ ์˜์ฒ ์ด์˜ Naive ๊ตฌํ˜„ (Bad Case)

์˜์ฒ ์ด๋Š” ์Šคํฌ๋กค ์œ„์น˜๋ฅผ ํ™•์ธํ•˜๊ณ  ์‹ถ์–ด์„œ scrollTop์„ ์ฝ์€ ์งํ›„, style.height๋ฅผ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋ธŒ๋ผ์šฐ์ €๋Š” ๋”์ฐํ•œ ๋น„ํšจ์œจ์„ ๊ฒช๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

// ๐Ÿฃ ์˜์ฒ : "์Šคํฌ๋กค ์œ„์น˜๋ฅผ ํ™•์ธํ•˜๊ณ , ๊ทธ์— ๋งž์ถฐ ๋†’์ด๋ฅผ ์กฐ์ ˆํ•ด์•ผ์ง€!"
function adjustLayout() {
    const container = document.getElementById('container');
    
    // โš ๏ธ 1. ์ฝ๊ธฐ (Read): ๋ ˆ์ด์•„์›ƒ ์ •๋ณด ์š”์ฒญ
    const currentScroll = container.scrollTop; 
    
    // โš ๏ธ 2. ์“ฐ๊ธฐ (Write): ๋ ˆ์ด์•„์›ƒ ๋ณ€๊ฒฝ
    container.style.height = (currentScroll + 100) + 'px'; 
    
    // โš ๏ธ 3. ๋‹ค์‹œ ์ฝ๊ธฐ (Read): ๋ฐฉ๊ธˆ ๋ฐ”๋€ ๋†’์ด๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•ด์•ผ ํ•จ!
    console.log(container.offsetHeight); // โŒ ์—ฌ๊ธฐ์„œ Reflow ๊ฐ•์ œ ๋ฐœ์ƒ!
}

๐Ÿฆ ์˜ํ˜ธ์˜ ํŒฉํญ ์กฐ์–ธ
"์˜์ฒ  ๋‹˜, scrollTop์„ ์ฝ๊ณ  ๋ฐ”๋กœ height๋ฅผ ๋ฐ”๊พธ๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” '์•„์ฐจ, ๋ฐฉ๊ธˆ ๋ฐ”๋€ ๋†’์ด๋กœ ๋‹ค์‹œ ๊ณ„์‚ฐํ•ด์•ผ๊ฒ ๋„ค?'๋ผ๋ฉฐ 1๋ฒˆ๋ถ€ํ„ฐ 4๋ฒˆ๊นŒ์ง€์˜ ๊ณผ์ •์„ ๊ฐ•์ œ๋กœ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฑธ **๋ ˆ์ด์•„์›ƒ ์Šค๋ž˜์‹ฑ(Layout Thrashing)**์ด๋ผ๊ณ  ํ•ด์š”. ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฉˆ์ถ”๋Š” ์ฃผ๋ฒ”์ด์ฃ ."

๐Ÿฆ ์˜ํ˜ธ์˜ ์•„ํ‚คํ…์ฒ˜ ๊ฐ€์ด๋“œ (Good Case)

์˜ํ˜ธ ๋ฆฌ๋“œ๋Š” ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ ์ž‘์—…์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ๋„ํ•ฉ๋‹ˆ๋‹ค.

// ๐Ÿฆ ์˜ํ˜ธ: "์ฝ์„ ๊ฑด ๋‹ค ์ฝ๊ณ , ์“ธ ๊ฑด ๋‹ค ์“ฐ์„ธ์š”. ์ค‘๊ฐ„์— ๋ผ์–ด๋“ค์ง€ ๋งˆ์„ธ์š”!"
function adjustLayoutOptimized() {
    const container = document.getElementById('container');
    
    // 1. ์ฝ๊ธฐ ์ž‘์—… ๋ชจ์œผ๊ธฐ (Read Batch)
    // ์ด ๋‹จ๊ณ„์—์„œ ๋ธŒ๋ผ์šฐ์ €๋Š” ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ตœ๋Œ€ํ•œ ์บ์‹ฑํ•ฉ๋‹ˆ๋‹ค.
    const currentScroll = container.scrollTop;
    const currentHeight = container.offsetHeight;
 
    // 2. ์“ฐ๊ธฐ ์ž‘์—… ๋ชจ์œผ๊ธฐ (Write Batch)
    // ๊ณ„์‚ฐ๋œ ๊ฐ’์œผ๋กœ ํ•œ ๋ฒˆ์— ์Šคํƒ€์ผ์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
    container.style.height = (currentScroll + 100) + 'px';
    
    // 3. ์ด์ œ ์ฝ์–ด๋„ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. (์ด๋ฏธ ๊ณ„์‚ฐ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜)
    console.log(container.offsetHeight); // โœ… Reflow ์—†์Œ!
}

๐Ÿ“Š ๋ ˆ๋ฒจ๋ณ„ ๋‹ต๋ณ€ ๊ฐ€์ด๋“œ (Self-Check)

  • Level 1 (Junior): "Reflow๋Š” ์š”์†Œ์˜ ํฌ๊ธฐ๋‚˜ ์œ„์น˜๊ฐ€ ๋ฐ”๋€Œ์–ด ๋ ˆ์ด์•„์›ƒ์„ ์žฌ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์ด๊ณ , Repaint๋Š” ์ƒ‰์ƒ์ด๋‚˜ ๋ฐฐ๊ฒฝ ๋“ฑ ์‹œ๊ฐ์  ์Šคํƒ€์ผ๋งŒ ๋ฐ”๋€Œ์–ด ๋‹ค์‹œ ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Reflow๊ฐ€ ๋” ๋น„์šฉ์ด ๋งŽ์ด ๋“ญ๋‹ˆ๋‹ค."
  • Level 2 (Senior): "Reflow๋Š” DOM ํŠธ๋ฆฌ ์ „์ฒด ๋˜๋Š” ์ผ๋ถ€์˜ ๊ธฐํ•˜ํ•™์  ๊ตฌ์กฐ๋ฅผ ์žฌ๊ณ„์‚ฐํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. width, height, margin, padding, font-size ๋ณ€๊ฒฝ ์‹œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. Repaint๋Š” ๋ ˆ์ด์•„์›ƒ์€ ์œ ์ง€๋œ ์ฑ„ ์ƒ‰์ƒ๋งŒ ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. color, background-color ๋ณ€๊ฒฝ ์‹œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค."
  • Level 3 (Specialist): "๋ ˆ์ด์•„์›ƒ ์Šค๋ž˜์‹ฑ(Layout Thrashing)์„ ์–ธ๊ธ‰ํ•˜๋ฉฐ, ์ฝ๊ธฐ(Read)์™€ ์“ฐ๊ธฐ(Write) ์ž‘์—…์„ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ ์ตœ์ ํ™” ์ „๋žต์ž„์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, transform, opacity๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Reflow์™€ Paint ๋‹จ๊ณ„๋ฅผ ๊ฑด๋„ˆ๋›ฐ๊ณ  Composite ๋‹จ๊ณ„์—์„œ ์ฒ˜๋ฆฌ๋˜์–ด ๊ฐ€์žฅ ๋น ๋ฅด๋‹ค๋Š” ์ ์„ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค."

๐Ÿฃ ์˜์ฒ ์ด์˜ ๋ณต๊ธฐ ์ผ๊ธฐ

์˜ค๋Š˜ '์˜์ˆ˜๋„ค ๊ฒŒ์‹œํŒ'์˜ ์„ฑ๋Šฅ ์ €ํ•˜ ์›์ธ์„ ์ฐพ์•˜๋‹ค. ๋ฆฌ์ŠคํŠธ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ๋ธŒ๋ผ์šฐ์ € ์‹ฌ์žฅ์„ ์ฅ์–ด์งœ๊ณ  ์žˆ์—ˆ๊ตฌ๋‚˜... ๐Ÿ˜ญ DocumentFragment๋ผ๋Š” ํ›Œ๋ฅญํ•œ ๋„๊ตฌ๊ฐ€ ์žˆ๋Š”๋ฐ ์™œ ์“ฐ์งˆ ๋ชปํ–ˆ๋‹ˆ!

๐Ÿ’ก "๋ธŒ๋ผ์šฐ์ €์˜ ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์€ ์ •ํ•ด์ง„ ์‹ ํ˜ธ ์ฒด๊ณ„๊ฐ€ ์žˆ๋Š” ๊ณ ์†๋„๋กœ์™€ ๊ฐ™๋‹ค. ๋‚ด ์ฝ”๋“œ๊ฐ€ ์—ญ์ฃผํ–‰์ธ์ง€ ์ˆœํ•ญ์ธ์ง€ ๋Š˜ ์ฒดํฌํ•˜์ž."

๋‚ด์ผ์€ ์ด๋ฒคํŠธ ๋ฃจํ”„๋ผ๋Š” ์‹ ํ˜ธ๋“ฑ ์ฒด๊ณ„๋ฅผ ์˜ํ˜ธ ๋‹˜๊ป˜ ์ œ๋Œ€๋กœ ๋ฐฐ์›Œ๋ด์•ผ๊ฒ ๋‹ค. ํ‡ด๊ทผํ•˜๊ณ  ์‹œ์›ํ•œ ๋งฅ์ฃผ ํ•œ ์ž” ํ•˜๋ฉด์„œ ์˜ค๋Š˜ ๋ณต๊ธฐ ๋! ๐Ÿบ


๐Ÿ”— ๋” ์•Œ์•„๋ณด๊ธฐ