Virtual DOM

1. ๊ฐœ์š”

๋ฆฌ์•กํŠธ์˜ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” VirtualDOM(๊ฐ€์ƒ๋”)์ด๋‹ค. VirtrualDOM๋ฅผ ์‚ดํŽด๋ณด๊ธฐ ์•ž์„œ DOM์˜ ๊ฐœ๋…์— ๋Œ€ํ•ด ๋จผ์ € ์•Œ์•„๋ณด๊ณ  VirtualDOM์˜ ํŠน์ง•์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์ž.


2. DOM์˜ ๊ฐœ๋…

DOM(Document Object Model, ๋ฌธ์„œ ๊ฐ์ฒด ๋ชจ๋ธ)์€ XML์ด๋‚˜ HTML๋ฌธ์„œ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์ผ์ข…์˜ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ์ด ๊ฐ์ฒด ๋ชจ๋ธ์€ ๋ฌธ์„œ ๋‚ด์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ •์˜ํ•˜๊ณ , ๊ฐ๊ฐ์˜ ์š”์†Œ์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค. ์ฆ‰ DOM์ด๋ž€ ์›น ๋ฌธ์„œ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์„œ๋ฅผ ํ•ด์„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋งํ•œ๋‹ค.

์›น ๋ฌธ์„œ์˜ ๋ชจ๋“  Element์™€ Attribute, Text๋“ค์„ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ๊ฐ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค๊ณ  ์ด ๊ฐ์ฒด๋“ค์„ ๊ด€๊ณ„๋ฅผ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๊ตฌ์ •ํ•œ ๊ฒƒ์ด DOM์ด๋‹ค.

์ฝ˜์†” ์ฐฝ์— DOM์˜ ์š”์†Œ ์ค‘ ํ•˜๋‚˜์ธ documnet๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

DOM console

์ฝ˜์†”์— ์ถœ๋ ฅ๋˜๋Š” ๊ฐ’์„ ํŽผ์ณ๋ณด๋ฉด ์›น ๋ฌธ์„œ์˜ ๊ตฌ์กฐ๊ฐ€ ๋“ค์–ด์žˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ DOM์ด๊ณ , ์šฐ๋ฆฌ๋Š” DOM๋ฅผ ์ด์šฉํ•˜์—ฌ ์›น ๋ฌธ์„œ๋ฅผ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

3. DOM์˜ ํŠธ๋ฆฌ ๊ตฌ์กฐ

<!DOCTYPE html>
<html>
  <head>
    <title>DOM์ด๋ž€?</title>
  </head>
  <body>
    <h1 class="title">์ œ๋ชฉ</h1>
    <p class="content">๋ณธ๋ฌธ ์˜์—ญ์ž…๋‹ˆ๋‹ค.</p>
  </body>
</html>

์œ„์˜ ์›น๋ฌธ์„œ๋ฅผ DOM์˜ ํŠธ๋ฆฌ๊ตฌ์กฐ๋กœ ๋‚˜ํƒ€๋‚ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ณ„์ธต ๊ตฌ์กฐ๋กœ ํ‘œํ˜„๋œ๋‹ค.

DOM tree

DOM์˜ ํŠธ๋ฆฌ๊ตฌ์กฐ๋Š” ๋…ธ๋“œ์™€ ๊ฐ€์ง€๋กœ ํ‘œํ˜„ํ•œ๋‹ค. ๋„ค๋ชจ ์ƒ์ž๊ฐ€ ๋…ธ๋“œ์ด๊ณ  ๋…ธ๋“œ์™€ ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ ๊ด€๊ณ„๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ์žˆ๋Š” ์„ ์ด ๊ฐ€์ง€์ด๋‹ค. ๋…ธ๋“œ๋Š” HTML์˜ ํƒœ๊ทธ ์š”์†Œ๋งŒ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ชจ๋“  ํ…์ŠคํŠธ, ์ด๋ฏธ์ง€, ํƒœ๊ทธ์˜ ์†์„ฑ๋“ค๊นŒ์ง€ ๊ฐ์ฒดํ™”ํ•˜์—ฌ DOMํŠธ๋ฆฌ์— ํ‘œํ˜„ํ•œ๋‹ค.

  1. ๋ฌธ์„œ ๋…ธ๋“œ (Document Node) ํŠธ๋ฆฌ์˜ ์ตœ์ƒ์œ„์— ์กด์žฌํ•˜๋ฉฐ, ํ•˜์œ„ ์ž์‹ ๋…ธ๋“œ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„  Document Node๋ฅผ ํ†ตํ•ด์•ผ๋งŒ ํ•œ๋‹ค. DOMํŠธ๋ฆฌ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์‹œ์ž‘์ ์ด๋‹ค.

  2. ์š”์†Œ ๋…ธ๋“œ (Element Node) ์›น ๋ฌธ์„œ์˜ ํƒœ๊ทธ๋Š” Element Node๋กœ ํ‘œํ˜„๋œ๋‹ค. ๋ชจ๋“  Element Node๋Š” Attribute Node์™€ Text Node๋ฅผ ์ž์‹์œผ๋กœ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ์ž์‹ ๋…ธ๋“œ๋“ค์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์›น ํŽ˜์ด์ง€๋ฅผ ๋™์ ์œผ๋กœ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

  3. ์†์„ฑ ๋…ธ๋“œ (Attribute Node) ํƒœ๊ทธ์˜ ๋ชจ๋“  ์†์„ฑ์€ Attribute Node๋กœ ํ‘œํ˜„ํ•˜๋ฉฐ ํ•ด๋‹น ํƒœ๊ทธ์˜ ์ž์‹ ๋…ธ๋“œ๋กœ ์ธ์‹๋œ๋‹ค.

  4. ํ…์ŠคํŠธ ๋…ธ๋“œ (Text Node) ํƒœ๊ทธ๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ…์ŠคํŠธ๋Š” ํ•ด๋‹น Element Node์˜ ์ž์‹ ๋…ธ๋“œ์ธ Text Node๋กœ ํ‘œํ˜„๋œ๋‹ค. Text Node๋Š” DOMํŠธ๋ฆฌ์˜ ๊ฐ€์žฅ ์•„๋ž˜์ชฝ์— ์œ„์น˜ํ•˜์—ฌ ์ž์‹ ์˜ ์ž์‹ ๋…ธ๋“œ๋Š” ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค.

  5. ์ฃผ์„ ๋…ธ๋“œ (Comment Node) ์ฃผ์„์€ Comment Node๋กœ ํ‘œํ˜„ํ•œ๋‹ค.

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


4. DOM์˜ ๋ฌธ์ œ์™€ ๋ธŒ๋ผ์šฐ์ €์˜ ๋žœ๋”๋ง ๋ฐฉ๋ฒ•

DOM์˜ ๋ฌธ์ œ๋ผ๊ณ  ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋‘ ๊ฐ€์ € ์ ์„ ๋ฝ‘์„ ์ˆ˜ ์žˆ๋‹ค.

  1. DOM์กฐ์ž‘์— ์˜ํ•œ ๋ Œ๋”๋ง์ด ๋น„ํšฐ์ 

  2. SPAํŠน์ง•์œผ๋กœ DOM ๋ณต์žก๋„ ์ฆ๊ฐ€์— ๋”ฐ๋ฅธ ์ตœ์ ํ™” ๋ฐ ์œ ์ง€ ๋ณด์ˆ˜๊ฐ€ ๋” ์–ด๋ ค์›Œ ์ง

DOM์„ ํ†ตํ•ด ๋™์ ์œผ๋กœ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผ ํ•œ๋‹ค.

document.getElementById("hello").innerHTML = "hello world!";
document.body.style.backgound = "blue";

์ด๋Ÿฌํ•œ ๊ณผ์ •์„ ํ†ตํ•ด ์›น ๋ธŒ๋ผ์šฐ์ €๋Š” DOM์ด ๋ณ€๊ฒฝ๋œ ๊ฒƒ์„ ์ธ์ง€ํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ € ์—”์ง„์„ ๋‹ค์‹œ ๋žœ๋”๋ง ํ•œ๋‹ค.

๋ธŒ๋ผ์šฐ์ € ์—”์ง„์€ User Interface์™€ Rendering Engine ์‚ฌ์ด์˜ ๋™์ž‘์„ ์ œ์–ดํ•ด์ฃผ๋Š” ์—”์ง„์ด๋‹ค. ์ด์™€๊ด€๋ จํ•ด์„œ๋Š” ๋ธŒ๋ผ์šฐ์ €์— ๋Œ€ํ•œ ๊ณต๋ถ€๋ฅผ ํ•  ๋•Œ ๋”ฐ๋กœ ์ •๋ฆฌ๋ฅผ ํ•˜๊ฒ ๋‹ค.

๋ธŒ๋ผ์šฐ์ €์˜ ๋žœ๋”๋ง ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณด๋ฉด์„œ ์œ„์˜ DOM ๋ Œ๋”๋ง ๋ฌธ์ œ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž. ์•„๋ž˜๋Š” ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง ๊ณผ์ •์„ ๊ทธ๋ฆผ์„ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ์ด๋‹ค.

Browser Rendering
  • ๋ Œ๋”๋ง ๊ณผ์ •

    1. HTML์„ ํŒŒ์‹ฑํ•˜์—ฌ DOM ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , css์„ ํŒŒ์‹ฑํ•˜์—ฌ ์Šคํƒ€์ผ ๊ทœ์น™์„ ๋งŒ๋“ ๋‹ค.

    2. ์ด ๋‘๊ฐœ๋ฅผ ํ•ฉ์ณ ์‹ค์ œ๋กœ ์›น ๋ธŒ๋ผ์šฐ์ €์— ๋ณด์—ฌ์ ธ์•ผํ•  ์š”์†Œ๋ฅผ ํ‘œํ˜„ํ•œ "๋ Œ๋” ํŠธ๋ฆฌ"๋ฅผ ๋งŒ๋“ ๋‹ค.

    3. ์ด ๋ Œ๋” ํŠธ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ ˆ์ด์•„์›ƒ์„ ๋ฐฐ์น˜๊ณ  ์ƒ‰์„ ์น ํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ํ•œ๋‹ค.

DOM์„ ๋ณ€๊ฒฝํ•  ๋•Œ ๋งˆ๋‹ค ์œ„์˜ ๋žœ๋”๋ง ๊ณผ์ •์„ ์—ฌ๋Ÿฌ๋ฒˆ ํ•˜๊ฒŒ ๋œ๋‹ค. DOM์„ 100๋ฒˆ ๋ณ€๊ฒฝํ•  ๋•Œ 100๋ฒˆ์˜ ๊ฐ€๊นŒ์šด ๋ Œ๋”๋ง์„ ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„ํšจ์œจ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.(100๋ฒˆ๋ณด๋‹ค ๋‚ฎ๋‹ค๊ณ  ํ•˜์ง€๋งŒ ๋น ๋ฅธ ์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•ด ๊ทธ๋ƒฅ 100๋ฒˆ์ด๋ผ๊ณ  ํ•˜๊ฒ ๋‹ค.)

์•„๋ž˜์˜ ์˜ˆ์‹œ ๋‚ด์šฉ์„ ๋ณด๋ฉฐ ์ดํ•ด๋ฅผ ํ•ด๋ณด์ž

<!DOCTYPE html>
<html>
  <head>
    <title>DOM์ด๋ž€?</title>
  </head>
  <body>
    <ul>
      <li>์›์ˆญ์ด</li>
      <li>์‚ฌ์ž</li>
      <li>ํ˜ธ๋ž‘์ด</li>
    </ul>
  </body>
</html>

์œ„์™€ ๊ฐ™์€ ํŽ˜์ด์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. DOM๋ฅผ ์ด์šฉํ•˜์—ฌ li๋…ธ๋“œ๋“ค์˜ ์ปจํ…์ธ ๋ฅผ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.

const liTags = document.querySelectorAll("li");

// ํ™”๋ฉด ๋ Œ๋”๋ง1 ๋ฐœ์ƒ
liTags[0].textContents = "๊ฐ•์•„์ง€";

// ํ™”๋ฉด ๋ Œ๋”๋ง2 ๋ฐœ์ƒ
liTags[1].textContents = "๊ณ ์–‘์ด";

// ํ™”๋ฉด ๋ Œ๋”๋ง3 ๋ฐœ์ƒ
liTags[2].textContents = "์•ต๋ฌด์ƒˆ";

์œ„์˜ ๊ณผ์ •์„ ๋ณด๋ฉด ํ•˜๋‚˜์˜ ์—…๋ฐ์ดํŠธ๋งˆ๋‹ค ๋ทฐ์˜ ๋ณ€ํ™” ์ƒ๊ธฐ๋ฉด ๊ทธ ๋•Œ ๋งˆ๋‹ค ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋‹ค์‹œ ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๋Š” ๊ณผ์ •์ด ์‹œ์ž‘๋˜๊ณ  ์ด ๋ถ€๋ถ„์ด ์žฆ์€ ๋”์ž‘์œผ๋กœ ์ƒ๊ธฐ๋Š” ์„ฑ๋Šฅ์˜ ๋ณ‘๋ชฉ์ ์ด ๋œ๋‹ค.


5. VirtualDOM

VirtualDOM์€ ์—ฌ๋Ÿฌ ์ˆ˜์ • ์‚ฌํ•ญ์ด ์žˆ๋”๋ผ๋„ ํ•œ ๋ฒˆ๋งŒ ๋ Œ๋”๋ง์„ ์‹คํ–‰ํ•œ๋‹ค. ๋˜ํ•œ DOM๋ฅผ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•œ ํ›„ ๋ Œ๋”๋ง ํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋€ ๋ถ€๋ถ„๋งŒ ์ฐพ์•„์„œ ํ•ด๋‹น ๋ถ€๋ถ„๋งŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

VirtualDOM1

์œ„์˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ VirtualDOM์€ DOM์ด ์ƒ์„ฑํ•˜๊ธฐ ์ „, ์ด์ „ ์ƒํƒœ ๊ฐ’๊ณผ ์ˆ˜์ •์‚ฌํ•ญ์„ ๋น„๊ตํ•˜์—ฌ ๋‹ฌ๋ผ์ง„ ๋ถ€๋ถ„๋งŒ DOM์—๊ฒŒ ํ•œ ๋ฒˆ๋งŒ ์ „๋‹ฌํ•˜์—ฌ ๋”ฑ ํ•œ ๋ฒˆ์˜ ๋ Œ๋”๋ง์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

VirtualDOM2

์œ„์˜ ๊ทธ๋ฆผ์˜ ์ฒซ๋ฒˆ์งธ DOM์˜ ์ƒํƒœ๋ฅผ ๋ณด์ž. ๋นจ๊ฐ„์ƒ‰ ๋ถ€๋ถ„์ด ๋ฐ”๋กœ ์ˆ˜์ •๋œ ๋ถ€๋ถ„์ด๋‹ค. VirtualDOM์€ ์Šค์Šค๋กœ ๋‹ฌ๋ผ์ง„ ๋ถ€๋ถ„์˜ ๊ฐ’์„ ํƒ์ง€ํ•˜๊ณ  ์ˆ˜์ •ํ•˜์—ฌ ์‹ค์ œ DOM์—๊ฒŒ ์ „๋‹ฌํ•œ๋‹ค. ๋งŒ์•ฝ VirtaulDOM์ด ์—†์—ˆ๋‹ค๋ฉด ๋ชจ๋“  ๋ถ€๋ถ„์ด ๋ Œ๋”๋ง ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ „๋ถ€๋‹ค ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ๋ฐ”๋€Œ์—ˆ์„ ๊ฒƒ์ด๋‹ค.


6. Diffing Algorithm

์•„๋ž˜๋Š” React doc์—์„œ ์„ค๋ช…ํ•˜๋Š” VirtualDOM์˜ ๊ฐœ๋…์ด๋‹ค.

The virtual DOM (VDOM) is a programming concept where an ideal, or โ€œvirtualโ€, representation of a UI is kept in memory and synced with the โ€œrealโ€ DOM by a library such as ReactDOM. This process is called reconciliation.

๋ฆฌ์•กํŠธ์—์„œ๋Š” VirtaulDOM์ด ReactDOM๊ณผ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ์‹ค์ œDOM๊ณผ ์—ฐ๋™์‹œ์ผœ์ค€๋‹ค๊ณ  ํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ๊ณผ์ •์„ "reconciliation"์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

์ด๋•Œ diffing ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ด์šฉํ•ด ๋ Œ๋”๋ง์„ ํ•œ๋‹ค.

์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด์„œ ๋ฆฌ์•กํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€, ์–ด๋–ค ๊ทœ์น™์ด ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด์ž.


6-1. Elements Of Different Types

์ƒ์œ„ root element๊ฐ€ ๋ฐ”๋€Œ๋ฉด ํ•˜์œ„ element๋„ ํ•จ๊ป˜ ๋ฐ”๋€๋‹ค.

import React from "react";
import Hedaer from "./Header";

function App() {
  return (
    <div>
      <Header />
    </div>
  );
}

// ์ƒ์œ„ํƒœ๊ทธ div๊ฐ€ span์œผ๋กœ ๋ฐ”๋€๋‹ค.
function App() {
  return (
    <span>
      <Header />
    </span>
  );
}

์œ„์˜ ์ฝ”๋“œ๋ฅผ ์„ค๋ช…ํ•˜์ž๋ฉด ์ƒ์œ„์— ์žˆ๋Š” divํƒœ๊ทธ๊ฐ€ span์œผ๋กœ ๋ฐ”๋€Œ์—ˆ๋‹ค. ์ด๋Ÿด ๊ฒฝ์šฐ Header์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š๋”๋ผ๊ณ  ๋ฆฌ์•กํŠธ๋Š” ์ƒˆ๋กœ์šด DOM๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.


6-2. DOM Elements Of The Same Type

์ด๋ฒˆ์—๋Š” element(์š”์†Œ)๋Š” ๊ฐ™์ง€๋งŒ attribute(์†์„ฑ)์ด ๋‹ฌ๋ผ์ง€๋Š” ๊ฒฝ์šฐ์ด๋‹ค. ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ 

import React from "react";
import Hedaer from "./Header";

function App() {
  return (
    <div className="after">
      <Header />
    </div>
  );
}

// ์ƒ์œ„ํƒœ๊ทธ div์˜ className์ด ๋ฐ”๋€๋‹ค.
function App() {
  return (
    <div className="before">
      <Header />
    </div>
  );
}

์ด์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ๋ฆฌ์•กํŠธ๋Š” ๋‘ attribute(์†์„ฑ)์„ ๋น„๊ตํ•˜์—ฌ ๋ฐ”๋€ ๋ถ€๋ถ„๋งŒ ๋ณ€ํ™”์‹œํ‚จ๋‹ค.


6-3. Recursing On Children

ํ•˜์œ„(์ž์‹) ์š”์†Œ๊ฐ€ ์ถ”๊ฐ€๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ณด์ž.

import React from "react";

function App() {
  return (
    <ul>
      <li>๊ฐ•์•„์ง€</li>
      <li>๊ณ ์–‘์ด</li>
    </ul>
  );
}

// ์„ธ๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ๋งŒ ์ถ”๊ฐ€
function App() {
  return (
    <ul>
      <li>๊ฐ•์•„์ง€</li>
      <li>๊ณ ์–‘์ด</li>
      <li>๊ฑฐ๋ถ์ด</li>
    </ul>
  );
}

๋ฆฌ์•กํŠธ๋Š” diffing ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ฒซ๋ฒˆ์งธ, ๋‘๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๊ฐ™์€ ๊ฒƒ์„ ํ™•์ธํ•˜์˜€๊ณ  ์„ธ๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ๋งŒ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์„ธ๋ฒˆ์งธ element(์—ฌ์‹œ์„œ๋Š” <li>๊ฑฐ๋ถ์ด</li>)๋งŒ ์ถ”๊ฐ€ํ•œ๋‹ค. ๋งŒ์•ฝ ๊ธฐ์กด DOM๋ฐฉ์‹์ด์—ˆ๋‹ค๋ฉด ๋ชจ๋‘ ๋‹ค์‹œ ๋žœ๋”๋ง์ด ๋˜์—ˆ์„ ๊ฒƒ์ด๋‹ค.

ํ•˜์ง€๋งŒ ์ฒซ๋ฒˆ์žฌ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋‘๋ฒˆ์งธ๊ฐ€ ๋˜๊ณ  ์ƒˆ๋กœ์šด ์ฒซ๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ƒ๊ธฐ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?(์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ )

import React from "react";

function App() {
  return (
    <ul>
      <li>๊ฐ•์•„์ง€</li>
      <li>๊ณ ์–‘์ด</li>
    </ul>
  );
}

// ๊ฑฐ๋ถ์ด ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ฒซ๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ๋กœ ์ถ”๊ฐ€
function App() {
  return (
    <ul>
      <li>๊ฑฐ๋ถ์ด</li>
      <li>๊ฐ•์•„์ง€</li>
      <li>๊ณ ์–‘์ด</li>
    </ul>
  );
}

์ด๋Ÿฐ ๊ฒฝ์šฐ๋Š” ๋ฆฌ์•กํŠธ๋Š” ์ฒซ ๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๊ฐ•์•„์ง€์—์„œ ๊ฑฐ๋ถ์ด๋กœ ๋ฐ”๋€ ๊ฒƒ์„ ์•Œ์•„์ฑ„๊ณ  li์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ƒˆ๋กœ ๋žœ๋”๋ง ํ•œ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด key props๋ฅผ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.


6-4. key

๋ฆฌ์•กํŠธ์—์„œ ์šฐ๋ฆฌ๊ฐ€ Array.map()๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ key ์†์„ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ ์ด์œ ๊ฐ€ ๋ฐ”๋€Œ๋Š” ๊ฐ’์ด ์žˆ๊ณ  ์ˆœ์„œ๋„ ๋ฐ”๋€Œ์—ˆ์„ ๊ฒฝ์šฐ DOM์ด ์ฒ˜์Œ๋ถ€ํ„ฐ ์ƒˆ๋กญ๊ฒŒ ๋ Œ๋”๋ง์„ ํ•˜์ง€ ์•Š๊ฒŒ ์œ„ํ•ด์„œ๋‹ค.

'6-3. Recursing On Children'์—์„œ์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด๋ณด์ž.

import React from "react";

function App() {
  return (
    <ul>
      <li key="1">๊ฐ•์•„์ง€</li>
      <li key="2">๊ณ ์–‘์ด</li>
    </ul>
  );
}

// ๊ฑฐ๋ถ์ด ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ฒซ๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ๋กœ ์ถ”๊ฐ€
function App() {
  return (
    <ul>
      <li key="3">๊ฑฐ๋ถ์ด</li>
      <li key="1">๊ฐ•์•„์ง€</li>
      <li key="2">๊ณ ์–‘์ด</li>
    </ul>
  );
}

์œ„์™€ ๊ฐ™์ด ๊ฐ ์š”์†Œ์— key๋ฅผ ์ง€์ •ํ•ด์ฃผ๋ฉด ์ƒˆ๋กœ์šด ์š”์†Œ๊ฐ€ ์ถ”๊ฐ€๋˜๊ณ  ์ˆœ์„œ๊ฐ€ ๋‹ฌ๋ผ์ง€๋”๋ผ๋„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ Œ๋”๋ง์„ ํ•˜์ง€ ์•Š๊ณ  ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธด ๋ถ€๋ถ„๋งŒ ๋ Œ๋”๋ง ํ•ด์ค€๋‹ค. ๋‹จ key์†์„ฑ์˜ ๊ฐ’์€ ๊ณ ์œ ๊ฐ’์ด์—ฌ์•ผ ํ•œ๋‹ค. ์ฆ‰ ์ค‘๋ณต๋˜์„œ๋Š” ์•ˆ๋œ๋‹ค.

key๋ฅผ ๊ตณ์ด ์ง€์ •ํ•˜์ง€ ์•Š์•„๋„ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์ง€ ์•Š๊ณ  ๋ฐ”๋€ ๋ถ€๋ถ„์ด ํ™”๋ฉด์— ์ž˜ ๋‚˜ํƒ€๋‚œ๋‹ค. ํ•˜์ง€๋งŒ ๋ฆฌ์•กํŠธ์—์„œ warning ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด์ค€๋‹ค. ์ด๋Š” DOM ๋ Œ๋”๋ง์—์„œ ์„ฑ๋Šฅ์ด ์ €ํ•˜๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์ ์„ ์‚ด๋ฆฌ๊ธฐ ์œ„ํ•ด key๋ฅผ ์ง€์ •ํ•ด ๋‘๋„๋ก ํ•˜์ž.

์•„๋ž˜๋Š” ๋ฆฌ์•กํŠธ๋กœ ๊ฐœ๋ฐœ์„ ํ•  ๊ฒฝ์šฐ ์ž์ฃผ ๋ณด๊ฒŒ ๋˜๋Š” array์™€ Array.map()๋ฉ”์†Œ๋“œ ๊ทธ๋ฆฌ๊ณ  key props์ด๋‹ค.

import React from "react";

function App() {
  const colors = ["black", "red", "blue", "white"];

  return (
    <ul>
      {colors.map((color, index) => (
        <li key={index}>{color}</li>
      ))}
    </ul>
  );
}

7. React Fiber

Fiber์€ React16์˜ ์ƒˆ๋กœ์šด reconciliation์—”์ง„์ด๋‹ค. Fiber์˜ ์ฃผ์š” ๋ชฉํ‘œ๋Š” VirtualDOM์˜ incremental rendering๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. React Fiber Architecture

React Fiber์— ๋Œ€ํ•ด์„œ๋Š” ํ•œ ์ฑ•ํ„ฐ๋กœ ๋”ฐ๋กœ ์ •๋ฆฌ๋ฅผ ํ•˜๋„๋ก ํ•˜์ž.


8. Conclusion

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฐฐ์šธ ๋•Œ ๊ณต๋ถ€ํ–ˆ๋˜ DOM์˜ ๋‚ด์šฉ์ด ์–ด๋ ดํ’‹์ด ๊ธฐ์–ต์ด ๋‚ฌ๋‹ค. ๋‚˜๋Š” DOM์„ ์‚ฌ์šฉํ•ด์„œ HTML์„ ์กฐ์ž‘ํ–ˆ์„ ๋•Œ ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ง€๊ณ  ๋ณต์žกํ•ด์ง„๋‹ค๋ผ๋Š” ๋А๋‚Œ์ด ๋“ค์—ˆ์ง€๋งŒ DOM์„ ์‚ฌ์šฉํ•ด์„œ HTML์˜ ์š”์†Œ๋ฅผ ๋ฐ”๋€Œ๋Š” ๊ฒƒ์— ์žฌ๋ฏธ๋ฅผ ๋А๊ผˆ์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ ๋ฆฌ์•กํŠธ๋ฅผ ๋ฐฐ์šฐ๋‹ˆ ๋ฐฐ์› ๋˜ DOM๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„ ๊ธฐ์–ต ์†์— ์ž ์‹œ ๋ฌป์–ด๋‘์—ˆ๋‹ค.(์•„์ฃผ ๊ฐ„ํ˜น ์‚ฌ์šฉํ•˜์˜€๋‹ค. NextJS ๋ฐฐ์šธ๋•Œ) ๋ฆฌ์•กํŠธ์—์„œ์˜ VirtualDOM์ด DOM์˜ ๋น„ํšจ์œจ์ ์ธ(๊ทธ๋ ‡๋‹ค๊ณ  ์—„์ฒญ ๋น„ํšจ์œจ์ ์ด์ง„ ์•Š์€ ๊ฑฐ ๊ฐ™๋‹ค.) ๋ Œ๋”๋ง ๋ฐฉ์‹์„ ๋ณด์™„ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ์ด๋ฒˆ ๊ณต๋ถ€๋ฅผ ํ†ตํ•ด ์•Œ๊ฒŒ ๋˜์—ˆ๊ณ  ๋‚ด๊ฐ€ ์•„๋ฌด๋Ÿฐ ์ƒ๊ฐ์—†์ด ์งฐ๋˜ ์ฝ”๋“œ๋“ค์ด VirtualDOM๋ฅผ ํ™œ์šฉํ•œ ๋ฐฉ์‹์ด๋ผ๋Š” ๊ฒƒ์— ๋†€๋ผ์› ๋‹ค. ์—ญ์‹œ ๊ณต๋ถ€๋ฅผ ํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ณต๋ถ€ํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํฐ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ๋“ฏ ํ•˜๋‹ค.๐Ÿง ๊ทธ๋ฆฌ๊ณ  ์ด์ „์— ํŒ€์›๊ณผ ์ฝ”๋“œ๋ฅผ ํ•จ๊ป˜ ๋ณด๋ฉฐ ๊ณต๋ถ€๋ฅผ ํ•˜๋‹ค๊ฐ€ ํ•œ ํŒ€์›์ด key props๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„ warning ๋ฉ”์„ธ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ์„ ๋ณด์•˜๋‹ค. ๋‚˜๋Š” key props๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ด์•ผ๊ธฐ ํ–ˆ๊ณ  ์–ด๋– ํ•œ ์ด์œ ์ธ์ง€๊นŒ์ง€๋Š” ์„ค๋ช…์„ ๋ชปํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ง€๊ธˆ์€ ์ž์‹ ์žˆ๊ฒŒ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ ๊ฐ™๋‹ค.๐Ÿ˜€ ๋์œผ๋กœ ๊ณต๋ถ€๋ฅผ ํ•˜๋ฉด์„œ ์ •๋ฆฌ๋ฅผ ํ•˜๊ณ  ์žˆ๋Š”๋ฐ ๋‚ด๊ฐ€ ์šฉ์–ด๋ฅผ ์ž˜ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€ ์ž˜๋ชป๋œ ์ •๋ณด๊ฐ€ ์—†๋Š”์ง€ ๊ฑฑ์ •์ด ๋œ๋‹ค. ์ด๋ฅผ ๋ณด์‹  ๋ถ„๋“ค ์ค‘ ์ž˜๋ชป๋œ ์ •๋ณด๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ผญ ๊นƒํ—ˆ๋ธŒ์ด์Šˆ๋ฅผ ํ†ตํ•ด ์•Œ๋ ค์ฃผ์‹œ๊ธธ ๋ฐ”๋ž€๋‹ค.


์ฐธ๊ณ 

[JS/DOM] ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ, ๋ฌธ์„œ ๊ฐ์ฒด ๋ชจ๋ธ(Document Object Model)์— ๋Œ€ํ•˜์—ฌ DOM์˜ ๊ฐœ๋… Virtual DOM ๋™์ž‘ ์›๋ฆฌ์™€ ์ดํ•ด (with ๋ธŒ๋ผ์šฐ์ €์˜ ๋ Œ๋”๋ง ๊ณผ์ •) ์™œ Virtual DOM์€ ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง ํšŸ์ˆ˜๋ฅผ ์ค„์—ฌ์ฃผ๋Š”๊ฐ€? DOM๊ณผ Virtual Dom์ด๋ž€? ๋ฆฌ์•กํŠธ: Virtual DOM(๊ฐ€์ƒ๋”, ๋ฒ„์ถ”์–ผ๋”)์ด๋ž€? React, diffing ์•Œ๊ณ ๋ฆฌ์ฆ˜


๐Ÿ“… 2022-07-16

Last updated