Front-end/React

[React] Diff Algorithm: ๋ณ€ํ™” ๊ฐ์ง€์˜ ๋งˆ๋ฒ•์„ ์•Œ์•„๋ณด์ž! ๐Ÿ”

xeunnie 2024. 12. 27. 01:00
728x90
๋ฐ˜์‘ํ˜•

๐Ÿ” Diff Algorithm: ํ†บ์•„๋ณด๊ธฐ!

Diff Algorithm(๋””ํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜)์€ ๋‘ ๊ฐœ์˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๋น„๊ตํ•ด์„œ ๋ณ€ํ™”๋œ ๋ถ€๋ถ„(์ฐจ์ด์ )์„ ์ฐพ์•„๋‚ด๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด์—์š”. ์ด ๊ธฐ์ˆ ์€ ํŠนํžˆ React์™€ ๊ฐ™์€ ํ˜„๋Œ€ ํ”„๋ก ํŠธ์—”๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•˜๊ณ , ์†Œ์Šค ์ฝ”๋“œ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ(์˜ˆ: Git)์—์„œ๋„ ํ•ต์‹ฌ์ ์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ Diff Algorithm์˜ ์›๋ฆฌ๋ถ€ํ„ฐ ์‹ค๋ฌด ํ™œ์šฉ๊นŒ์ง€, ๋””ํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋ชจ๋“  ๊ฒƒ์„ ๊นŠ์ด ์žˆ๊ฒŒ ํŒŒํ—ค์ณ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿ› ๏ธ


๐Ÿ“Œ Diff Algorithm์ด๋ž€?

Diff Algorithm์€ ๋‘ ๋ฐ์ดํ„ฐ์˜ ์ฐจ์ด์ ์„ ์ฐพ์•„๋‚ด๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€, ์‚ญ์ œ, ๋˜๋Š” ์ˆ˜์ •๋˜์—ˆ๋Š”์ง€ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ๋‘ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค.

 

Original: "Hello, World!"
Modified: "Hello, React World!"

 

Diff Algorithm์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋„์ถœํ•ฉ๋‹ˆ๋‹ค:

๐Ÿ‘‰ “React”๋ผ๋Š” ๋ฌธ์ž์—ด์ด ์ถ”๊ฐ€๋จ.


๐Ÿค” Diff Algorithm์€ ์–ด๋””์— ์“ฐ์ด๋‚˜์š”?

1. Git๊ณผ ๊ฐ™์€ ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ

Git์€ Diff Algorithm์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ์ฝ”๋“œ ์ƒํƒœ์˜ ์ฐจ์ด๋ฅผ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ณ€๊ฒฝ๋œ ์ค„์„ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜, ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ๋ณ‘ํ•ฉํ•  ๋•Œ ๋„์›€์„ ์ค๋‹ˆ๋‹ค.

2. React์™€ Virtual DOM

React๋Š” UI ์—…๋ฐ์ดํŠธ ์‹œ, ๊ธฐ์กด DOM๊ณผ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ๋œ Virtual DOM ๊ฐ„์˜ ์ฐจ์ด์ ์„ ์ฐพ์•„๋‚ด์–ด ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์‹ค์ œ DOM์— ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ Diff Algorithm์ด ํ•ต์‹ฌ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

3. ํ…์ŠคํŠธ ๋น„๊ต ๋„๊ตฌ

Diff Algorithm์€ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋„๊ตฌ, ๋ฌธ์„œ ๋น„๊ต ์†Œํ”„ํŠธ์›จ์–ด ๋“ฑ์—์„œ๋„ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ“‚ Diff Algorithm์˜ ๊ธฐ๋ณธ ๋™์ž‘ ์›๋ฆฌ

Diff Algorithm์€ ๋‘ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ(์ฃผ๋กœ ํŠธ๋ฆฌ ๋˜๋Š” ๋ฌธ์ž์—ด)๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ตœ์†Œํ•œ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ฐพ์•„๋‚ด๋Š” ๋ฐ ์ดˆ์ ์„ ๋งž์ถฅ๋‹ˆ๋‹ค.

 

1. ๋ฌธ์ž์—ด ๋น„๊ต

  • Longest Common Subsequence (LCS): ๋ฌธ์ž์—ด ๋น„๊ต์˜ ํ•ต์‹ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฌธ์ž์—ด์—์„œ ๊ฐ€์žฅ ๊ธด ๊ณตํ†ต ๋ถ€๋ถ„ ๋ฌธ์ž์—ด์„ ์ฐพ์•„๋‚ด๊ณ , ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ ์‚ฝ์ž…/์‚ญ์ œ/์ˆ˜์ •์œผ๋กœ ๋ถ„๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค.

Original: "abcd"

Modified: "acbd"

Result:

  - ์‚ญ์ œ: "b"

  - ์ถ”๊ฐ€: "b" (๋‹ค๋ฅธ ์œ„์น˜)

 

2. ํŠธ๋ฆฌ ๊ตฌ์กฐ ๋น„๊ต

React์™€ ๊ฐ™์€ ํ”„๋ก ํŠธ์—”๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋Š” ํŠธ๋ฆฌ ๊ตฌ์กฐ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ๋•Œ๋ฌธ์— Tree Diff Algorithm์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋“œ ๊ฐ„์˜ ์ฐจ์ด๋ฅผ ์ตœ์†Œํ•œ์œผ๋กœ ๊ณ„์‚ฐํ•˜์—ฌ ํšจ์œจ์ ์ธ ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ” React์˜ Diff Algorithm

React๋Š” Virtual DOM์„ ์‚ฌ์šฉํ•ด ํšจ์œจ์ ์ธ UI ์—…๋ฐ์ดํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ Diff Algorithm์ด ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ด์š”.

  1. React์˜ Diff Algorithm ํŠน์ง•
    • O(n)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๋Š” ํšจ์œจ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • ์ „์ฒด DOM์„ ๋น„๊ตํ•˜์ง€ ์•Š๊ณ , ๋‘ ๊ฐœ์˜ Virtual DOM ๊ฐ„์˜ ์ฐจ์ด๋งŒ ์ฐพ์•„๋ƒ…๋‹ˆ๋‹ค.
  2. React์˜ Tree Diff
    • ๋™์ผํ•œ ๋ ˆ๋ฒจ์˜ ๋…ธ๋“œ๋งŒ ๋น„๊ต: React๋Š” ํŠธ๋ฆฌ์˜ ๊นŠ์ด๋ฅผ ๋”ฐ๋ผ ๋‚ด๋ ค๊ฐ€๋ฉฐ ๋™์ผํ•œ ๋ถ€๋ชจ ์•„๋ž˜์˜ ์ž์‹ ๋…ธ๋“œ๋ผ๋ฆฌ๋งŒ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.
    • ๋…ธ๋“œ ์žฌ์‚ฌ์šฉ: ๋™์ผํ•œ key๋ฅผ ๊ฐ€์ง„ ๋…ธ๋“œ๋Š” ์žฌ์‚ฌ์šฉํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ:

// ์ด์ „ Virtual DOM
<ul>
  <li key="1">Apple</li>
  <li key="2">Banana</li>
</ul>

// ์ƒˆ๋กœ์šด Virtual DOM
<ul>
  <li key="1">Apple</li>
  <li key="3">Cherry</li>
</ul>

 

React์˜ Diff Algorithm ๊ฒฐ๊ณผ:

  • key="1": ๋™์ผ, ์žฌ์‚ฌ์šฉ
  • key="2": ์ œ๊ฑฐ
  • key="3": ์ถ”๊ฐ€

๐Ÿ› ๏ธ Diff Algorithm์˜ ๊ตฌํ˜„

1. ๊ธฐ๋ณธ ๋ฌธ์ž์—ด Diff

๋ฌธ์ž์—ด ๊ฐ„ ์ฐจ์ด๋ฅผ ๋น„๊ตํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

function diffStrings(original, modified) {
  const originalArr = original.split('');
  const modifiedArr = modified.split('');
  const result = [];
  
  for (let i = 0; i < modifiedArr.length; i++) {
    if (originalArr[i] !== modifiedArr[i]) {
      result.push({ index: i, original: originalArr[i], modified: modifiedArr[i] });
    }
  }
  return result;
}

const original = "abcd";
const modified = "acbd";
console.log(diffStrings(original, modified));

/*
[
  { index: 1, original: 'b', modified: 'c' },
  { index: 2, original: 'c', modified: 'b' }
]
*/

 

2. React์˜ Virtual DOM Diff ์‹œ๋ฎฌ๋ ˆ์ด์…˜

React์˜ ๊ธฐ๋ณธ Diff Algorithm ๋™์ž‘์„ ๋‹จ์ˆœํ™”ํ•œ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

function diffTrees(oldTree, newTree) {
  if (!oldTree && newTree) {
    return "Node added";
  }
  if (oldTree && !newTree) {
    return "Node removed";
  }
  if (oldTree.type !== newTree.type) {
    return "Node replaced";
  }
  return "Node updated";
}

const oldTree = { type: "div", props: { className: "old" } };
const newTree = { type: "div", props: { className: "new" } };

console.log(diffTrees(oldTree, newTree)); // Node updated

๐Ÿšฉ Diff Algorithm์˜ ์ฃผ์š” ๊ณผ์ œ์™€ ํ•œ๊ณ„

1. ์„ฑ๋Šฅ

๋ณต์žกํ•œ ๊ตฌ์กฐ์—์„œ๋Š” Diff Algorithm์ด ๋งŽ์€ ๊ณ„์‚ฐ์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด React๋Š” O(n) ๋ณต์žก๋„์˜ ํŠธ๋ฆฌ ๋น„๊ต๋ฅผ ์ฑ„ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.

2. Key ์†์„ฑ

React์˜ Diff Algorithm์—์„œ key๋Š” ์„ฑ๋Šฅ๊ณผ ์ •ํ™•์„ฑ์„ ๋†’์ด๋Š” ์ค‘์š”ํ•œ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ๊ณ ์œ ํ•œ key๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋ฉด, ๋ถˆํ•„์š”ํ•œ DOM ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ”ฎ ์‹ค๋ฌด์—์„œ์˜ ํ™œ์šฉ

  1. Git
    • ๋ณ€๊ฒฝ๋œ ์ฝ”๋“œ๋งŒ ๋ณ‘ํ•ฉ
    • git diff ๋ช…๋ น์–ด๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ ํ™•์ธ
  2. React
    • ํšจ์œจ์ ์ธ UI ์—…๋ฐ์ดํŠธ
    • shouldComponentUpdate์™€ ๊ฐ™์€ ์ตœ์ ํ™” ๋„๊ตฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ
  3.  ๋ฌธ์„œ ๋น„๊ต
    • Markdown ์—๋””ํ„ฐ์—์„œ ์‹ค์‹œ๊ฐ„ ๋น„๊ต.

๐ŸŒŸ ๋งˆ๋ฌด๋ฆฌ

Diff Algorithm์€ ํšจ์œจ์ ์ธ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ๊ฐ์ง€๋ฅผ ์œ„ํ•œ ์ค‘์š”ํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ React์™€ ๊ฐ™์€ ํ˜„๋Œ€์ ์ธ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์—์„œ๋Š” ํ•„์ˆ˜์ ์ธ ๊ธฐ์ˆ ๋กœ ์ž๋ฆฌ ์žก๊ณ  ์žˆ์–ด์š”. ์ด๋ฅผ ์ดํ•ดํ•˜๋ฉด ์„ฑ๋Šฅ ์ตœ์ ํ™”์™€ ์œ ์—ฐํ•œ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ์— ํ•œ ๊ฑธ์Œ ๋” ๊ฐ€๊นŒ์›Œ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๐ŸŒท์ „์„ค์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์–ด๋ด…์‹œ๋‹น! ๐ŸŒท

728x90
๋ฐ˜์‘ํ˜•