[๐Ÿค–] ์›น ์„ฑ๋Šฅ ์ตœ์ ํ™”: ๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ ์ตœ์†Œํ™” ์ „๋žต

๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง ๊ณผ์ •์˜ ํ•ต์‹ฌ์ธ ๋ฆฌํ”Œ๋กœ์šฐ(Reflow)์™€ ๋ฆฌํŽ˜์ธํŠธ(Repaint)์˜ ๋ฐœ์ƒ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ณ , ์ด๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ค„์—ฌ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ๊ทน๋Œ€ํ™”ํ•˜๋Š” ์‹ค์งˆ์ ์ธ ์ „๋žต๊ณผ ์ฝ”๋“œ ์˜ˆ์‹œ๋ฅผ ์ž์„ธํžˆ ์•Œ๋ ค๋“œ๋ ค์š”.

26๋ถ„
๋‹จ์–ด: 2,181๊ฐœ
๊ฒŒ์‹œ๊ธ€ ์ธ๋„ค์ผ
์ •๋ณด

๐Ÿค– ์ด ํฌ์ŠคํŒ…์€ Gemini 2.5 Flash AI๊ฐ€ ์ž‘์„ฑํ–ˆ์–ด์š”.
๋‚ด์šฉ์˜ ์ •ํ™•์„ฑ์„ ์œ„ํ•ด ๊ฒ€ํ† ๋ฅผ ๊ฑฐ์ณค์ง€๋งŒ, ์‹ค๋ฌด ์ ์šฉ ์ „ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ํ•จ๊ป˜ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

์œ ์šฉํ•œ ํŒ

๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ค๋Š” ๋ฆฌํ”Œ๋กœ์šฐ(Reflow)์™€ ๋ฆฌํŽ˜์ธํŠธ(Repaint)์˜ ๊ฐœ๋…์„ ์ดํ•ดํ•˜๊ณ , ์‹ค์งˆ์ ์ธ ์ฝ”๋“œ ์ตœ์ ํ™” ๊ธฐ๋ฒ•์„ ํ†ตํ•ด ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฐ˜์‘์„ฑ๊ณผ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์›Œ๋ด์š”.

์•ˆ๋…•ํ•˜์„ธ์š”! ์‹œ๋‹ˆ์–ด ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž ๋ธ”๋ฃจ์˜ˆ์š”. ์›น ๊ฐœ๋ฐœ์„ ํ•˜๋ฉด์„œ "๋‚ด ์›น์‚ฌ์ดํŠธ๊ฐ€ ์™œ ์ด๋ ‡๊ฒŒ ๋А๋ฆฌ์ง€?"๋ผ๋Š” ๊ณ ๋ฏผ์„ ํ•ด๋ณด์‹  ์ ์ด ์žˆ์œผ์‹ ๊ฐ€์š”? ํŠนํžˆ ๋™์ ์ธ UI๋‚˜ ๋ณต์žกํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ตฌํ˜„ํ•  ๋•Œ ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ์ž์ฃผ ๊ฒช๊ฒŒ ๋˜๋Š”๋ฐ์š”.
์˜ค๋Š˜์€ ์›น ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ํ•ต์‹ฌ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜์ธ **๋ฆฌํ”Œ๋กœ์šฐ(Reflow)**์™€ **๋ฆฌํŽ˜์ธํŠธ(Repaint)**์— ๋Œ€ํ•ด ๊นŠ์ด ํŒŒ๊ณ ๋“ค์–ด ๋ณด๊ณ , ์ด๋“ค์„ ํšจ๊ณผ์ ์œผ๋กœ ์ตœ์†Œํ™”ํ•˜์—ฌ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฐ˜์‘์„ฑ๊ณผ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํฌ๊ฒŒ ๊ฐœ์„ ํ•˜๋Š” ์‹ค์งˆ์ ์ธ ์ „๋žต๋“ค์„ ์•Œ๋ ค๋“œ๋ฆด๊ฒŒ์š”.

๐Ÿค” ๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ, ์™œ ์ค‘์š”ํ•œ๊ฐ€์š”?

0๏ธโƒฃ ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง์˜ ๊ธฐ๋ณธ ๊ณผ์ •

์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ HTML, CSS, JavaScript ์ฝ”๋“œ๊ฐ€ ์›น ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด์— ๊ทธ๋ ค์ง€๊ธฐ๊นŒ์ง€๋Š” ์—ฌ๋Ÿฌ ๋‹จ๊ณ„์˜ ๋ณต์žกํ•œ ๊ณผ์ •์ด ํ•„์š”ํ•ด์š”.
์ด ๊ณผ์ •์„ ๊ฐ„๋‹จํžˆ ์š”์•ฝํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์•„์š”.

  1. DOM ํŠธ๋ฆฌ ๊ตฌ์ถ• (DOM Tree): HTML์„ ํŒŒ์‹ฑํ•˜์—ฌ DOM(Document Object Model) ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด์š”.
  2. CSSOM ํŠธ๋ฆฌ ๊ตฌ์ถ• (CSSOM Tree): CSS๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ CSSOM(CSS Object Model) ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด์š”.
  3. ๋ Œ๋” ํŠธ๋ฆฌ ๊ตฌ์ถ• (Render Tree): DOM ํŠธ๋ฆฌ์™€ CSSOM ํŠธ๋ฆฌ๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ๋ Œ๋” ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ด์š”. ๋ Œ๋” ํŠธ๋ฆฌ๋Š” ํ™”๋ฉด์— ๋ Œ๋”๋ง๋  ์š”์†Œ๋“ค(visibility: hidden์€ ํฌํ•จํ•˜์ง€๋งŒ display: none์€ ์ œ์™ธ)์˜ ๋ ˆ์ด์•„์›ƒ ์ •๋ณด์™€ ์Šคํƒ€์ผ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์–ด์š”.
  4. ๋ ˆ์ด์•„์›ƒ (Layout / Reflow): ๋ Œ๋” ํŠธ๋ฆฌ์˜ ๊ฐ ๋…ธ๋“œ์— ๋Œ€ํ•ด ํ™”๋ฉด์ƒ์˜ ์ •ํ™•ํ•œ ์œ„์น˜์™€ ํฌ๊ธฐ๋ฅผ ๊ณ„์‚ฐํ•ด์š”. ์ด ๊ณผ์ •์„ '๋ ˆ์ด์•„์›ƒ' ๋˜๋Š” '๋ฆฌํ”Œ๋กœ์šฐ'๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ต๋‹ˆ๋‹ค.
  5. ํŽ˜์ธํŠธ (Paint / Repaint): ๊ณ„์‚ฐ๋œ ๋ ˆ์ด์•„์›ƒ ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ํ”ฝ์…€์„ ํ™”๋ฉด์— ๊ทธ๋ ค์š”. ์ด ๊ณผ์ •์„ 'ํŽ˜์ธํŠธ' ๋˜๋Š” '๋ฆฌํŽ˜์ธํŠธ'๋ผ๊ณ  ํ•ด์š”.
  6. ํ•ฉ์„ฑ (Compositing): ์—ฌ๋Ÿฌ ๋ ˆ์ด์–ด(Layer)๋กœ ๋‚˜๋‰œ ์š”์†Œ๋“ค์„ ํ•ฉ์„ฑํ•˜์—ฌ ์ตœ์ข… ํ™”๋ฉด์„ ์™„์„ฑํ•ด์š”.
์ •๋ณด

์ž ๊น! ๋ Œ๋”๋ง ๋ธ”๋กœํ‚น ๋ฆฌ์†Œ์Šค๋ž€?
HTML ํŒŒ์‹ฑ ์ค‘ <script> ํƒœ๊ทธ๋ฅผ ๋งŒ๋‚˜๋ฉด, ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๊ฐ€ DOM ํŠธ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŒŒ์‹ฑ์ด ์ค‘๋‹จ๋˜๊ณ  ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์š”.
๋˜ํ•œ, <link rel="stylesheet"> ๊ฐ™์€ CSS ํŒŒ์ผ์€ CSSOM ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•ด์•ผ ๋ Œ๋” ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ Œ๋”๋ง์„ ๋ธ”๋กœํ‚นํ•  ์ˆ˜ ์žˆ์–ด์š”.
์ด๋Ÿฐ ๋ฆฌ์†Œ์Šค๋“ค์€ ์›น ์„ฑ๋Šฅ์— ํฐ ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฃผ์˜ํ•ด์•ผ ํ•ด์š”.

1๏ธโƒฃ ๋ฆฌํ”Œ๋กœ์šฐ(Reflow)์™€ ๋ฆฌํŽ˜์ธํŠธ(Repaint)๋ž€?

๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ๋Š” ์›น ํŽ˜์ด์ง€์˜ ์„ฑ๋Šฅ์— ์ง์ ‘์ ์ธ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ํ•ต์‹ฌ์ ์ธ ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง ๋‹จ๊ณ„์˜ˆ์š”.
๋‘ ๊ฐ€์ง€ ๊ฐœ๋…์„ ์ข€ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณผ๊ฒŒ์š”.

  • ๋ฆฌํ”Œ๋กœ์šฐ (Reflow ๋˜๋Š” Layout):
    DOM ํŠธ๋ฆฌ์˜ ๊ตฌ์กฐ๋‚˜ ์š”์†Œ์˜ ํฌ๊ธฐ, ์œ„์น˜ ๋“ฑ ๋ ˆ์ด์•„์›ƒ์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•ด๋‹น ์š”์†Œ์™€ ๊ทธ ์ž์‹ ์š”์†Œ, ๊ทธ๋ฆฌ๊ณ  ์ฃผ๋ณ€ ์š”์†Œ๋“ค์˜ ํฌ๊ธฐ์™€ ์œ„์น˜๋ฅผ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๋Š” ๊ณผ์ •์ด์—์š”.
    ์˜ˆ๋ฅผ ๋“ค์–ด, ์š”์†Œ์˜ width, height, margin, padding, border, font-size, position, display ๋“ฑ์˜ ์†์„ฑ์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๋ฆฌํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•ด์š”. ๋ฆฌํ”Œ๋กœ์šฐ๋Š” ์ฃผ๋ณ€ ์š”์†Œ๋“ค์—๊ฒŒ๋„ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ์ž‘์—…์ด๋ž๋‹ˆ๋‹ค.

  • ๋ฆฌํŽ˜์ธํŠธ (Repaint ๋˜๋Š” Paint):
    ์š”์†Œ์˜ ๋ ˆ์ด์•„์›ƒ์—๋Š” ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์œผ๋ฉด์„œ ์‹œ๊ฐ์ ์ธ ์Šคํƒ€์ผ๋งŒ ๋ณ€๊ฒฝ๋  ๋•Œ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•ด๋‹น ์š”์†Œ์˜ ํ”ฝ์…€์„ ๋‹ค์‹œ ๊ทธ๋ฆฌ๋Š” ๊ณผ์ •์ด์—์š”.
    ์˜ˆ๋ฅผ ๋“ค์–ด, ์š”์†Œ์˜ color, background-color, visibility, opacity, box-shadow ๋“ฑ์˜ ์†์„ฑ์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๋ฆฌํŽ˜์ธํŠธ๊ฐ€ ๋ฐœ์ƒํ•ด์š”. ๋ฆฌํŽ˜์ธํŠธ๋Š” ๋ฆฌํ”Œ๋กœ์šฐ๋ณด๋‹ค๋Š” ๋น„์šฉ์ด ์ ๊ฒŒ ๋“ค์ง€๋งŒ, ์—ฌ์ „ํžˆ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์–ด์š”.

๊ฒฝ๊ณ 

๊ธฐ์–ตํ•˜์„ธ์š”!
๋ฆฌํ”Œ๋กœ์šฐ๋Š” ํ•ญ์ƒ ๋ฆฌํŽ˜์ธํŠธ๋ฅผ ๋™๋ฐ˜ํ•˜์ง€๋งŒ, ๋ฆฌํŽ˜์ธํŠธ๋Š” ๋ฆฌํ”Œ๋กœ์šฐ๋ฅผ ๋™๋ฐ˜ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์–ด์š”.
์ฆ‰, ๋ ˆ์ด์•„์›ƒ์ด ๋ณ€๊ฒฝ๋˜๋ฉด(๋ฆฌํ”Œ๋กœ์šฐ) ํ™”๋ฉด๋„ ๋‹ค์‹œ ๊ทธ๋ ค์•ผ ํ•˜์ง€๋งŒ(๋ฆฌํŽ˜์ธํŠธ), ์ƒ‰์ƒ๋งŒ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ(๋ฆฌํŽ˜์ธํŠธ) ๋ ˆ์ด์•„์›ƒ์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ํ•„์š”๋Š” ์—†๋‹ค๋Š” ์˜๋ฏธ์˜ˆ์š”.

2๏ธโƒฃ ์„ฑ๋Šฅ ์ €ํ•˜์˜ ์ฃผ๋ฒ” ๐Ÿ˜ข

๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ™”๋ฉด์„ ๊ฐฑ์‹ ํ•˜๋Š” ๋ฐ ํ•„์ˆ˜์ ์ธ ๊ณผ์ •์ด์ง€๋งŒ, ๋„ˆ๋ฌด ์ž์ฃผ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ํ•œ ๋ฒˆ์— ๋งŽ์€ ์š”์†Œ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋ฉด ์›น ํŽ˜์ด์ง€์˜ ๋ฐ˜์‘์„ฑ์„ ๋–จ์–ด๋œจ๋ฆฌ๊ณ , ๋ฒ„๋ฒ…๊ฑฐ๋ฆผ(jank) ํ˜„์ƒ์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์–ด์š”.
ํŠนํžˆ ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์ด๋‚˜ ์ €์‚ฌ์–‘ ๊ธฐ๊ธฐ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋”์šฑ ๋‘๋“œ๋Ÿฌ์ง€๊ฒŒ ๋‚˜ํƒ€๋‚œ๋‹ต๋‹ˆ๋‹ค.
์‚ฌ์šฉ์ž๋“ค์€ ๋А๋ฆฌ๊ณ  ๋ฒ„๋ฒ…๊ฑฐ๋ฆฌ๋Š” ์›น์‚ฌ์ดํŠธ๋ฅผ ์‹ซ์–ดํ•ด์š”. ๊ทธ๋ž˜์„œ ์ด๋“ค์„ ์ตœ์†Œํ™”ํ•˜๋Š” ๊ฒƒ์ด ์›น ์„ฑ๋Šฅ ์ตœ์ ํ™”์— ์žˆ์–ด์„œ ๋งค์šฐ ์ค‘์š”ํ•ด์š”.

๐Ÿš€ ๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ ์ตœ์†Œํ™” ์ „๋žต

์ด์ œ๋ถ€ํ„ฐ ์‹ค์งˆ์ ์œผ๋กœ ๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ์ „๋žต๋“ค์„ ์‚ดํŽด๋ณผ๊ฒŒ์š”.

0๏ธโƒฃ CSS ์†์„ฑ ์„ ํƒ์˜ ์ค‘์š”์„ฑ ๐ŸŽจ

๋ชจ๋“  CSS ์†์„ฑ์ด ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ Œ๋”๋ง ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์—์š”.
์–ด๋–ค ์†์„ฑ์€ ๋ฆฌํ”Œ๋กœ์šฐ๋ฅผ ์œ ๋ฐœํ•˜๊ณ , ์–ด๋–ค ์†์„ฑ์€ ๋ฆฌํŽ˜์ธํŠธ๋งŒ ์œ ๋ฐœํ•˜๋ฉฐ, ์–ด๋–ค ์†์„ฑ์€ ํ•ฉ์„ฑ(Compositing) ๋‹จ๊ณ„์—์„œ๋งŒ ์ฒ˜๋ฆฌ๋˜์–ด GPU ๊ฐ€์†์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด์š”.

  • ๋ฆฌํ”Œ๋กœ์šฐ ์œ ๋ฐœ ์†์„ฑ (๋น„์šฉ ๋†’์Œ):
    width, height, margin, padding, border, top, left, right, bottom, font-size, text-align, overflow, display, position, float ๋“ฑ ์š”์†Œ์˜ ๊ธฐํ•˜ํ•™์  ์ •๋ณด์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ๋ชจ๋“  ์†์„ฑ์ด์—์š”.

  • ๋ฆฌํŽ˜์ธํŠธ ์œ ๋ฐœ ์†์„ฑ (๋น„์šฉ ์ค‘๊ฐ„):
    color, background-color, visibility, box-shadow, text-decoration ๋“ฑ ๋ ˆ์ด์•„์›ƒ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ  ์‹œ๊ฐ์ ์ธ ํ‘œํ˜„๋งŒ ๋ณ€๊ฒฝํ•˜๋Š” ์†์„ฑ์ด์—์š”.

  • ํ•ฉ์„ฑ(Compositing)๋งŒ ์œ ๋ฐœํ•˜๋Š” ์†์„ฑ (๋น„์šฉ ๋‚ฎ์Œ, GPU ๊ฐ€์† ๊ฐ€๋Šฅ):
    opacity, transform (2D/3D) ๋“ฑ์˜ ์†์„ฑ์€ ์š”์†Œ์˜ ๋ ˆ์ด์–ด ์ž์ฒด๋ฅผ ์ด๋™ํ•˜๊ฑฐ๋‚˜ ๋ถˆํˆฌ๋ช…๋„๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•ด๋‹น ์š”์†Œ๋ฅผ ๋ณ„๋„์˜ ๋ ˆ์ด์–ด๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ GPU๋ฅผ ํ†ตํ•ด ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.
    ์ด๋Ÿฌํ•œ ์†์„ฑ๋“ค์€ ๋ฆฌํ”Œ๋กœ์šฐ๋‚˜ ๋ฆฌํŽ˜์ธํŠธ๋ฅผ ์œ ๋ฐœํ•˜์ง€ ์•Š๊ณ , ํ•ฉ์„ฑ ๋‹จ๊ณ„์—์„œ๋งŒ ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜์— ์‚ฌ์šฉํ•˜๋ฉด ๋งค์šฐ ํšจ์œจ์ ์ด์—์š”.

์œ ์šฉํ•œ ํŒ

ํ•ต์‹ฌ ์ „๋žต: ์• ๋‹ˆ๋ฉ”์ด์…˜์ด๋‚˜ ์ž์ฃผ ๋ณ€๊ฒฝ๋˜๋Š” ์†์„ฑ์—๋Š” transform์ด๋‚˜ opacity์™€ ๊ฐ™์ด ํ•ฉ์„ฑ๋งŒ ์œ ๋ฐœํ•˜๋Š” ์†์„ฑ์„ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”.
๋ถ€๋“์ดํ•˜๊ฒŒ ๋ ˆ์ด์•„์›ƒ ์†์„ฑ์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ๊ทธ ์˜ํ–ฅ์„ ์ตœ์†Œํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•„์•ผ ํ•ด์š”.

1๏ธโƒฃ DOM ๋ณ€๊ฒฝ ์ตœ์†Œํ™” ๋ฐ ํšจ์œจ์ ์ธ ์—…๋ฐ์ดํŠธ ๐Ÿ”„

DOM์„ ์ง์ ‘ ์กฐ์ž‘ํ•˜๋Š” ๊ฒƒ์€ ๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ๋ฅผ ๊ฐ€์žฅ ๋นˆ๋ฒˆํ•˜๊ฒŒ ์œ ๋ฐœํ•˜๋Š” ์›์ธ ์ค‘ ํ•˜๋‚˜์˜ˆ์š”.
๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ DOM ๋ณ€๊ฒฝ์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

  • ์Šคํƒ€์ผ ๋ณ€๊ฒฝ ์ผ๊ด„ ์ฒ˜๋ฆฌ:
    ์—ฌ๋Ÿฌ ๊ฐœ์˜ CSS ์†์„ฑ์„ ๊ฐœ๋ณ„์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ๊ฐ ๋ณ€๊ฒฝ๋งˆ๋‹ค ๋ฆฌํ”Œ๋กœ์šฐ/๋ฆฌํŽ˜์ธํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด์š”.
    ๋Œ€์‹ , CSS ํด๋ž˜์Šค๋ฅผ ํ† ๊ธ€ํ•˜๊ฑฐ๋‚˜ cssText ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•œ ๋ฒˆ์— ๋ชจ๋“  ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝํ•˜๋ฉด ์ข‹์•„์š”.

  • DOM ์กฐ์ž‘ ์ตœ์†Œํ™”:
    DOM ์š”์†Œ๋ฅผ ์ถ”๊ฐ€, ์‚ญ์ œ, ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค ๋ฆฌํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•ด์š”.
    ๊ฐ€๋Šฅํ•œ ํ•œ DOM ์กฐ์ž‘ ํšŸ์ˆ˜๋ฅผ ์ค„์ด๊ณ , ํ•„์š”ํ•˜๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด์š”.

    • DocumentFragment ์‚ฌ์šฉ:
      ์—ฌ๋Ÿฌ DOM ์š”์†Œ๋ฅผ ํ•œ ๋ฒˆ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ๋•Œ, DocumentFragment๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด DOM ํŠธ๋ฆฌ์— ํ•œ ๋ฒˆ๋งŒ ์ ‘๊ทผํ•˜์—ฌ ๋ฆฌํ”Œ๋กœ์šฐ๋ฅผ ํ•œ ๋ฒˆ๋งŒ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”.
      DocumentFragment๋Š” ์‹ค์ œ DOM ํŠธ๋ฆฌ์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฐ€์ƒ์˜ DOM ๋…ธ๋“œ์˜ˆ์š”.
    • ์š”์†Œ๋ฅผ DOM์—์„œ ๋ถ„๋ฆฌ ํ›„ ์กฐ์ž‘:
      ๋ณต์žกํ•œ DOM ์กฐ์ž‘์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ํ•ด๋‹น ์š”์†Œ๋ฅผ display: none์œผ๋กœ ์„ค์ •ํ•˜์—ฌ DOM์—์„œ ์ผ์‹œ์ ์œผ๋กœ ๋ถ„๋ฆฌํ•˜๊ฑฐ๋‚˜, remove() ๋ฉ”์„œ๋“œ๋กœ ์ œ๊ฑฐํ•œ ํ›„ ์กฐ์ž‘์„ ์™„๋ฃŒํ•˜๊ณ  ๋‹ค์‹œ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
      ์ด ๋ฐฉ๋ฒ•์€ ์กฐ์ž‘ ์ค‘์—๋Š” ๋ฆฌํ”Œ๋กœ์šฐ/๋ฆฌํŽ˜์ธํŠธ๋ฅผ ๋ฐฉ์ง€ํ•˜์ง€๋งŒ, display: none ์„ค์ • ๋ฐ ํ•ด์ œ ์‹œ, ๋˜๋Š” ์ถ”๊ฐ€/์ œ๊ฑฐ ์‹œ ๋ฆฌํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฃผ์˜ํ•ด์•ผ ํ•ด์š”.
  • ์ฝ๊ธฐ ์ž‘์—…๊ณผ ์“ฐ๊ธฐ ์ž‘์—… ๋ถ„๋ฆฌ:
    ๋ธŒ๋ผ์šฐ์ €๋Š” ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์—ฌ๋Ÿฌ ์“ฐ๊ธฐ(write) ์ž‘์—…์„ ํ์— ๋„ฃ์–ด๋’€๋‹ค๊ฐ€ ํ•œ๊บผ๋ฒˆ์— ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์–ด์š”.
    ํ•˜์ง€๋งŒ ์“ฐ๊ธฐ ์ž‘์—…(element.style.width = '100px')๊ณผ ์ฝ๊ธฐ ์ž‘์—…(element.offsetWidth)์ด ๋ฒˆ๊ฐˆ์•„ ๋ฐœ์ƒํ•˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ตœ์‹  ๋ ˆ์ด์•„์›ƒ ์ •๋ณด๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ๊ฐ•์ œ๋กœ ํ์— ์žˆ๋Š” ์“ฐ๊ธฐ ์ž‘์—…์„ ์ฆ‰์‹œ ์‹คํ–‰(๊ฐ•์ œ ๋™๊ธฐ ๋ ˆ์ด์•„์›ƒ)์‹œ์ผœ ๋ถˆํ•„์š”ํ•œ ๋ฆฌํ”Œ๋กœ์šฐ๋ฅผ ์œ ๋ฐœํ•ด์š”.
    ๋”ฐ๋ผ์„œ ์ฝ๊ธฐ ์ž‘์—…์€ ๋ชจ๋‘ ๋จผ์ € ์ˆ˜ํ–‰ํ•˜๊ณ , ๊ทธ ํ›„์— ์“ฐ๊ธฐ ์ž‘์—…์„ ์ผ๊ด„์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์•„์š”.

    // ๐Ÿ‘Ž ๋น„ํšจ์œจ์ ์ธ ์˜ˆ์‹œ (๊ฐ•์ œ ๋™๊ธฐ ๋ ˆ์ด์•„์›ƒ ๋ฐœ์ƒ) for (let i = 0; i < 100; i++) { el.style.width = (el.offsetWidth + 10) + 'px'; // ์ฝ๊ธฐ(offsetWidth) -> ์“ฐ๊ธฐ(width) ๋ฐ˜๋ณต } // ๐Ÿ‘ ํšจ์œจ์ ์ธ ์˜ˆ์‹œ (์ฝ๊ธฐ, ์“ฐ๊ธฐ ๋ถ„๋ฆฌ) let widths = []; for (let i = 0; i < 100; i++) { widths.push(el.offsetWidth); // ๋ชจ๋“  ์ฝ๊ธฐ ์ž‘์—… ๋จผ์ € ์ˆ˜ํ–‰ } for (let i = 0; i < 100; i++) { el.style.width = (widths[i] + 10) + 'px'; // ๋ชจ๋“  ์“ฐ๊ธฐ ์ž‘์—… ์ผ๊ด„ ์ฒ˜๋ฆฌ }

2๏ธโƒฃ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ตœ์ ํ™” โœจ

์• ๋‹ˆ๋ฉ”์ด์…˜์€ ์‹œ๊ฐ์  ๋ณ€ํ™”๊ฐ€ ์—ฐ์†์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ๋ฆฌํ”Œ๋กœ์šฐ/๋ฆฌํŽ˜์ธํŠธ์— ๋งค์šฐ ์ทจ์•ฝํ•ด์š”.
๋‹ค์Œ ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด ์• ๋‹ˆ๋ฉ”์ด์…˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”.

  • CSS transform๊ณผ opacity ์‚ฌ์šฉ:
    ์•ž์„œ ์„ค๋ช…ํ–ˆ๋“ฏ์ด, transform๊ณผ opacity๋Š” GPU ๊ฐ€์†์„ ํ™œ์šฉํ•˜์—ฌ ํ•ฉ์„ฑ ๋‹จ๊ณ„์—์„œ๋งŒ ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ ๊ฐ€์žฅ ์„ฑ๋Šฅ์ด ์ข‹์€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์†์„ฑ์ด์—์š”.
    left, top ๋Œ€์‹  transform: translate()๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

  • requestAnimationFrame ํ™œ์šฉ:
    JavaScript๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” setTimeout์ด๋‚˜ setInterval ๋Œ€์‹  requestAnimationFrame์„ ์‚ฌ์šฉํ•˜์„ธ์š”.
    requestAnimationFrame์€ ๋ธŒ๋ผ์šฐ์ €์˜ ๋ Œ๋”๋ง ์ฃผ๊ธฐ์™€ ๋™๊ธฐํ™”๋˜์–ด ๋‹ค์Œ ๋ฆฌํŽ˜์ธํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์ง์ „์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ด์š”.
    ์ด๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋Š๊น€ ์—†์ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋ณด์ด๋„๋ก ํ•˜๊ณ , ๋ถˆํ•„์š”ํ•œ ํ”„๋ ˆ์ž„ ๋“œ๋กญ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค˜์š”.

  • will-change ์†์„ฑ:
    CSS will-change ์†์„ฑ์€ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ "์ด ์š”์†Œ๊ฐ€ ๊ณง ๋ณ€๊ฒฝ๋  ๊ฒƒ์ด๋‹ˆ ๋ฏธ๋ฆฌ ์ตœ์ ํ™”ํ•ด ๋‘ฌ๋ผ"๊ณ  ํžŒํŠธ๋ฅผ ์ฃผ๋Š” ์—ญํ• ์„ ํ•ด์š”.
    ์˜ˆ๋ฅผ ๋“ค์–ด, will-change: transform, opacity;๋ฅผ ์„ค์ •ํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ํ•ด๋‹น ์š”์†Œ์— ๋Œ€ํ•œ ๋ ˆ์ด์–ด๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•˜์—ฌ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œ์ž‘ ์‹œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ดˆ๊ธฐ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”.
    ํ•˜์ง€๋งŒ ๋‚จ์šฉํ•˜๋ฉด ์˜คํžˆ๋ ค ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ๋Š˜๋ฆฌ๊ณ  ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ฌ ์ˆ˜ ์žˆ์œผ๋‹ˆ, ์‹ค์ œ๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์ ์šฉ๋  ์š”์†Œ์—๋งŒ ์‹ ์ค‘ํ•˜๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”.

    .animated-element { will-change: transform, opacity; /* ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์‹œ์ž‘๋˜๊ธฐ ์ „ ๋ฏธ๋ฆฌ ๋ธŒ๋ผ์šฐ์ €์— ํžŒํŠธ๋ฅผ ์ค๋‹ˆ๋‹ค. */ transition: transform 0.3s ease-out, opacity 0.3s ease-out; }

3๏ธโƒฃ JavaScript ์ตœ์ ํ™” ๊ธฐ๋ฒ• ๐Ÿ’ก

JavaScript ์ฝ”๋“œ๋„ ๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์–ด์š”.
๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋ฒ•์œผ๋กœ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

  • ์“ฐ๋กœํ‹€๋ง(Throttling)๊ณผ ๋””๋ฐ”์šด์‹ฑ(Debouncing):
    resize, scroll, mousemove์™€ ๊ฐ™์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ DOM ์กฐ์ž‘์ด๋‚˜ ๋ ˆ์ด์•„์›ƒ ๊ณ„์‚ฐ์ด ์ผ์–ด๋‚œ๋‹ค๋ฉด ์‹ฌ๊ฐํ•œ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์–ด์š”.
    ์ด๋Ÿฌํ•œ ์ด๋ฒคํŠธ์—๋Š” ์“ฐ๋กœํ‹€๋ง(์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰)์ด๋‚˜ ๋””๋ฐ”์šด์‹ฑ(๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ ๋ฐœ์ƒ ํ›„ ์ผ์ • ์‹œ๊ฐ„ ๋’ค ์‹คํ–‰)์„ ์ ์šฉํ•˜์—ฌ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ์‹คํ–‰ ํšŸ์ˆ˜๋ฅผ ์ œํ•œํ•ด์•ผ ํ•ด์š”.
  • Virtual DOM ํ™œ์šฉ (React, Vue ๋“ฑ):
    React๋‚˜ Vue ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” Virtual DOM์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ DOM ์กฐ์ž‘์„ ์ตœ์†Œํ™”ํ•ด์š”.
    ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด Virtual DOM์—์„œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ณ„์‚ฐํ•˜๊ณ , ์‹ค์ œ DOM๊ณผ์˜ ์ฐจ์ด(diff)๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ตœ์†Œํ•œ์˜ DOM ์กฐ์ž‘๋งŒ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.
    ๋ฌผ๋ก  Virtual DOM๋„ ๊ฒฐ๊ตญ ์‹ค์ œ DOM์„ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋ฆฌํ”Œ๋กœ์šฐ/๋ฆฌํŽ˜์ธํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ DOM์„ ์กฐ์ž‘ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด ์ค€๋‹ต๋‹ˆ๋‹ค.

๐Ÿงช ์‹ค์ „ ์ฝ”๋“œ ์˜ˆ์‹œ๋กœ ๋ฐฐ์šฐ๋Š” ์ตœ์ ํ™”

์ด์ œ ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์•ž์—์„œ ๋ฐฐ์šด ์ „๋žต๋“ค์„ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์‚ดํŽด๋ณผ๊ฒŒ์š”.

0๏ธโƒฃ CSS ์†์„ฑ ๋ณ€๊ฒฝ ์ตœ์ ํ™” ๐Ÿš€

๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์š”์†Œ์˜ ์œ„์น˜๋ฅผ ์ด๋™์‹œํ‚ค๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋งŒ๋“ ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด์š”.
left ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์™€ transform ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋น„๊ตํ•ด ๋ณผ๊ฒŒ์š”.

<style> .box { width: 100px; height: 100px; background-color: dodgerblue; position: relative; margin-bottom: 20px; } /* ๐Ÿ‘Ž left ์†์„ฑ ์‚ฌ์šฉ (๋ฆฌํ”Œ๋กœ์šฐ ์œ ๋ฐœ) */ .box-left { left: 0; transition: left 0.5s ease-out; } .box-left.move { left: 200px; } /* ๐Ÿ‘ transform ์†์„ฑ ์‚ฌ์šฉ (ํ•ฉ์„ฑ๋งŒ ์œ ๋ฐœ, GPU ๊ฐ€์†) */ .box-transform { transform: translateX(0); transition: transform 0.5s ease-out; } .box-transform.move { transform: translateX(200px); } </style> <div> <div id="boxLeft" class="box box-left"></div> <button onclick="toggleMove('boxLeft')">Move with Left</button> </div> <div> <div id="boxTransform" class="box box-transform"></div> <button onclick="toggleMove('boxTransform')">Move with Transform</button> </div> <script> function toggleMove(id) { const element = document.getElementById(id); element.classList.toggle('move'); } </script>
์œ ์šฉํ•œ ํŒ

๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ Performance ํƒญ์—์„œ ๋‘ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉฐ ๋ Œ๋”๋ง ๊ณผ์ •์„ ์‚ดํŽด๋ณด์„ธ์š”.
box-left๋Š” Layout(Reflow)๊ณผ Paint(Repaint)๊ฐ€ ๋ชจ๋‘ ๋ฐœ์ƒํ•˜๋Š” ๋ฐ˜๋ฉด, box-transform์€ ์ฃผ๋กœ Composite(ํ•ฉ์„ฑ) ๋‹จ๊ณ„์—์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”. transform์ด ํ›จ์”ฌ ํšจ์œจ์ ์ด์ฃ !

1๏ธโƒฃ DOM ์กฐ์ž‘ ์ตœ์ ํ™” ๐Ÿ”„

์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฆฌ์ŠคํŠธ ์•„์ดํ…œ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ๋•Œ, ๊ฐ ์•„์ดํ…œ์„ ๊ฐœ๋ณ„์ ์œผ๋กœ DOM์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ์™€ DocumentFragment๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋น„๊ตํ•ด ๋ณผ๊ฒŒ์š”.

<div> <h3>๊ฐœ๋ณ„ ์ถ”๊ฐ€ (๋น„ํšจ์œจ์ )</h3> <ul id="listIndividual"></ul> <button onclick="addItemsIndividual()">๊ฐœ๋ณ„ ์•„์ดํ…œ ์ถ”๊ฐ€</button> </div> <div> <h3>DocumentFragment ์‚ฌ์šฉ (ํšจ์œจ์ )</h3> <ul id="listFragment"></ul> <button onclick="addItemsFragment()">Fragment ์•„์ดํ…œ ์ถ”๊ฐ€</button> </div> <script> function createListItem(text) { const li = document.createElement('li'); li.textContent = text; return li; } function addItemsIndividual() { const list = document.getElementById('listIndividual'); // ๊ธฐ์กด ์•„์ดํ…œ ์ œ๊ฑฐ ํ›„ ๋‹ค์‹œ ์ถ”๊ฐ€ (์˜ˆ์‹œ๋ฅผ ์œ„ํ•ด) list.innerHTML = ''; console.time('addItemsIndividual'); for (let i = 0; i < 1000; i++) { list.appendChild(createListItem(`Item ${i}`)); // 1000๋ฒˆ์˜ DOM ์กฐ์ž‘ -> 1000๋ฒˆ์˜ ๋ฆฌํ”Œ๋กœ์šฐ/๋ฆฌํŽ˜์ธํŠธ ๊ฐ€๋Šฅ์„ฑ } console.timeEnd('addItemsIndividual'); } function addItemsFragment() { const list = document.getElementById('listFragment'); // ๊ธฐ์กด ์•„์ดํ…œ ์ œ๊ฑฐ ํ›„ ๋‹ค์‹œ ์ถ”๊ฐ€ (์˜ˆ์‹œ๋ฅผ ์œ„ํ•ด) list.innerHTML = ''; console.time('addItemsFragment'); const fragment = document.createDocumentFragment(); for (let i = 0; i < 1000; i++) { fragment.appendChild(createListItem(`Item ${i}`)); // Fragment์— ์ถ”๊ฐ€ -> DOM์—๋Š” ์•„์ง ์˜ํ–ฅ ์—†์Œ } list.appendChild(fragment); // ํ•œ ๋ฒˆ์˜ DOM ์กฐ์ž‘ -> ํ•œ ๋ฒˆ์˜ ๋ฆฌํ”Œ๋กœ์šฐ/๋ฆฌํŽ˜์ธํŠธ console.timeEnd('addItemsFragment'); } </script>
์„ฑ๊ณต

addItemsIndividual ํ•จ์ˆ˜๋Š” 1000๋ฒˆ์˜ appendChild ํ˜ธ์ถœ๋กœ ์ธํ•ด 1000๋ฒˆ์˜ ์ž ์žฌ์ ์ธ ๋ฆฌํ”Œ๋กœ์šฐ/๋ฆฌํŽ˜์ธํŠธ๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์–ด์š”.
๋ฐ˜๋ฉด, addItemsFragment ํ•จ์ˆ˜๋Š” DocumentFragment์— 1000๊ฐœ์˜ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•œ ํ›„, ์ตœ์ข…์ ์œผ๋กœ list.appendChild(fragment)๋ฅผ ํ†ตํ•ด ๋‹จ ํ•œ ๋ฒˆ๋งŒ DOM์— ์ ‘๊ทผํ•˜๋ฏ€๋กœ ํ›จ์”ฌ ํšจ์œจ์ ์ด์ฃ .

2๏ธโƒฃ ์• ๋‹ˆ๋ฉ”์ด์…˜์— requestAnimationFrame ํ™œ์šฉ โฑ๏ธ

JavaScript๋กœ ๋ถ€๋“œ๋Ÿฌ์šด ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ตฌํ˜„ํ•  ๋•Œ requestAnimationFrame์ด ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ์ง€ ๋ณด์—ฌ๋“œ๋ฆด๊ฒŒ์š”.
์—ฌ๊ธฐ์„œ๋Š” ๋ฐ•์Šค๋ฅผ ์›€์ง์ด๋Š” ๊ฐ„๋‹จํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ setInterval๊ณผ requestAnimationFrame์œผ๋กœ ๊ฐ๊ฐ ๊ตฌํ˜„ํ•ด ๋น„๊ตํ•ด ๋ณผ ์ˆ˜ ์žˆ์–ด์š”.

<style> .anim-box { width: 50px; height: 50px; background-color: purple; position: relative; left: 0; margin-bottom: 20px; } </style> <div> <h3>setInterval ์• ๋‹ˆ๋ฉ”์ด์…˜</h3> <div id="intervalBox" class="anim-box"></div> <button onclick="startIntervalAnimation()">์‹œ์ž‘</button> <button onclick="stopIntervalAnimation()">์ค‘์ง€</button> </div> <div> <h3>requestAnimationFrame ์• ๋‹ˆ๋ฉ”์ด์…˜</h3> <div id="rafBox" class="anim-box"></div> <button onclick="startRafAnimation()">์‹œ์ž‘</button> <button onclick="stopRafAnimation()">์ค‘์ง€</button> </div> <script> let intervalId; let rafId; function startIntervalAnimation() { const box = document.getElementById('intervalBox'); let position = 0; intervalId = setInterval(() => { position += 2; box.style.left = position + 'px'; // left ์†์„ฑ ๋ณ€๊ฒฝ์€ ๋ฆฌํ”Œ๋กœ์šฐ ์œ ๋ฐœ if (position > 200) { position = 0; } }, 16); // ์•ฝ 60fps (1000ms / 60 = 16.6ms) } function stopIntervalAnimation() { clearInterval(intervalId); } function startRafAnimation() { const box = document.getElementById('rafBox'); let position = 0; function animate() { position += 2; box.style.transform = `translateX(${position}px)`; // transform ์‚ฌ์šฉ์œผ๋กœ ํ•ฉ์„ฑ๋งŒ ์œ ๋ฐœ if (position > 200) { position = 0; } rafId = requestAnimationFrame(animate); // ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง ์ฃผ๊ธฐ์— ๋งž์ถฐ ํ˜ธ์ถœ } rafId = requestAnimationFrame(animate); } function stopRafAnimation() { cancelAnimationFrame(rafId); } </script>
์ •๋ณด

setInterval์€ ์ •ํ•ด์ง„ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ๋ฌด์กฐ๊ฑด ์ฝœ๋ฐฑ์„ ์‹คํ–‰ํ•ด์š”. ์ด๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ๋ Œ๋”๋ง ์ฃผ๊ธฐ์™€ ๋งž์ง€ ์•Š์„ ๊ฒฝ์šฐ ํ”„๋ ˆ์ž„ ๋“œ๋กญ์„ ์œ ๋ฐœํ•˜๊ฑฐ๋‚˜, ํ™”๋ฉด์ด ๊ทธ๋ ค์ง€๊ธฐ ์ „์— ๋ถˆํ•„์š”ํ•œ ๊ณ„์‚ฐ์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”.
๋ฐ˜๋ฉด requestAnimationFrame์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ™”๋ฉด์„ ๊ฐฑ์‹ ํ•˜๊ธฐ ์ „์— ๋”ฑ ํ•œ ๋ฒˆ๋งŒ ์ฝœ๋ฐฑ์„ ์‹คํ–‰ํ•˜๋„๋ก ๋ณด์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํ›จ์”ฌ ๋ถ€๋“œ๋Ÿฝ๊ณ  ํšจ์œจ์ ์ธ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

๐Ÿ“ ์ •๋ฆฌํ•˜๋ฉฐ

์›น ์„ฑ๋Šฅ ์ตœ์ ํ™”๋Š” ๋‹จ์ˆœํžˆ ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์†๋„๋งŒ์„ ์˜๋ฏธํ•˜์ง€ ์•Š์•„์š”.
์‚ฌ์šฉ์ž๊ฐ€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•  ๋•Œ ์–ผ๋งˆ๋‚˜ ๋ถ€๋“œ๋Ÿฝ๊ณ  ๋น ๋ฅด๊ฒŒ ๋ฐ˜์‘ํ•˜๋Š”์ง€๋„ ์ค‘์š”ํ•œ ์„ฑ๋Šฅ ์ง€ํ‘œ๊ฐ€ ๋œ๋‹ต๋‹ˆ๋‹ค.
์˜ค๋Š˜ ์šฐ๋ฆฌ๋Š” ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง์˜ ํ•ต์‹ฌ์ธ ๋ฆฌํ”Œ๋กœ์šฐ์™€ ๋ฆฌํŽ˜์ธํŠธ์˜ ๊ฐœ๋…์„ ์ดํ•ดํ•˜๊ณ , ์ด๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ์‹ค์งˆ์ ์ธ ์ „๋žต๋“ค์„ ๋ฐฐ์›Œ๋ดค์–ด์š”.

0๏ธโƒฃ ํ•ต์‹ฌ ์š”์•ฝ ๋ฐ ์‹ค์ฒœ ๊ฐ€์ด๋“œ โœ…

  • **๋ฆฌํ”Œ๋กœ์šฐ(Reflow)**๋Š” ๋ ˆ์ด์•„์›ƒ ๋ณ€๊ฒฝ ์‹œ ๋ฐœ์ƒํ•˜๋ฉฐ ๋น„์šฉ์ด ๊ฐ€์žฅ ๋†’์•„์š”.
  • **๋ฆฌํŽ˜์ธํŠธ(Repaint)**๋Š” ์‹œ๊ฐ์  ์Šคํƒ€์ผ ๋ณ€๊ฒฝ ์‹œ ๋ฐœ์ƒํ•˜๋ฉฐ ๋ฆฌํ”Œ๋กœ์šฐ๋ณด๋‹ค ๋น„์šฉ์ด ๋‚ฎ์•„์š”.
  • ์• ๋‹ˆ๋ฉ”์ด์…˜์—๋Š” transform, opacity์™€ ๊ฐ™์ด ํ•ฉ์„ฑ(Compositing)๋งŒ ์œ ๋ฐœํ•˜๋Š” CSS ์†์„ฑ์„ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”.
  • DOM ์กฐ์ž‘ ํšŸ์ˆ˜๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ณ , ์—ฌ๋Ÿฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ DocumentFragment๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ CSS ํด๋ž˜์Šค ํ† ๊ธ€ ๋“ฑ์œผ๋กœ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•˜์„ธ์š”.
  • element.offsetWidth ๊ฐ™์€ ์ฝ๊ธฐ ์ž‘์—…๊ณผ ์“ฐ๊ธฐ ์ž‘์—…์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ฐ•์ œ ๋™๊ธฐ ๋ ˆ์ด์•„์›ƒ์„ ํ”ผํ•˜์„ธ์š”.
  • JavaScript ์• ๋‹ˆ๋ฉ”์ด์…˜์—๋Š” requestAnimationFrame์„ ์‚ฌ์šฉํ•˜๊ณ , will-change ์†์„ฑ์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €์— ํžŒํŠธ๋ฅผ ์ฃผ์„ธ์š”.
  • resize, scroll ๋“ฑ ๋นˆ๋ฒˆํ•œ ์ด๋ฒคํŠธ์—๋Š” ์“ฐ๋กœํ‹€๋ง/๋””๋ฐ”์šด์‹ฑ์„ ์ ์šฉํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ์ค„์ด์„ธ์š”.

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

๐Ÿ“ฎ ์ฐธ๊ณ 

์—ฐ๊ด€๋œ ํฌ์ŠคํŠธ