Y J S

React์˜ DOM์— ๋Œ€ํ•ด์„œ

Virtual DOM์ด๋ž€?

Virtual DOM์€ ์‹ค์ œ DOM์˜ ๊ฐ€๋ฒผ์šด ๋ณต์‚ฌ๋ณธ์œผ๋กœ, ๋ฉ”๋ชจ๋ฆฌ์— ์กด์žฌํ•˜๋Š” JavaScript ๊ฐ์ฒด์ด๋‹ค. React๊ฐ€ UI ์—…๋ฐ์ดํŠธ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํ•ต์‹ฌ ๊ฐœ๋…์ด๋‹ค.

Virtual DOM์˜ ์ž‘๋™ ๋ฐฉ์‹

  1. State ๋ณ€๊ฒฝ ๊ฐ์ง€

    • ์ปดํฌ๋„ŒํŠธ์˜ state๋‚˜ props๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด React๋Š” ์ƒˆ๋กœ์šด Virtual DOM ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  2. Diffing ์•Œ๊ณ ๋ฆฌ์ฆ˜

    • ์ด์ „ Virtual DOM๊ณผ ์ƒˆ๋กœ์šด Virtual DOM์„ ๋น„๊ตํ•œ๋‹ค.
    • ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ์„ ์ฐพ์•„๋‚ด๋Š” ๊ณผ์ •์„ "์žฌ์กฐ์ •(Reconciliation)"์ด๋ผ๊ณ  ํ•œ๋‹ค.
  3. ๋ฐฐ์น˜ ์—…๋ฐ์ดํŠธ

    • ์ฐพ์•„๋‚ธ ์ฐจ์ด์ ๋“ค์„ ๋ชจ์•„์„œ ์‹ค์ œ DOM์— ํ•œ ๋ฒˆ์— ์ ์šฉํ•œ๋‹ค.
    • ์ด๋ฅผ ํ†ตํ•ด ๋ถˆํ•„์š”ํ•œ DOM ์กฐ์ž‘์„ ์ตœ์†Œํ™”ํ•œ๋‹ค.

Virtual DOM์˜ ์žฅ์ 

  1. ์„ฑ๋Šฅ ์ตœ์ ํ™”

    // ์˜ˆ์‹œ: ์—ฌ๋Ÿฌ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ
    function Counter() {
      const [count, setCount] = useState(0);
      return (
        <div>
          <h1>{count}</h1>
          <button onClick={() => setCount(count + 1)}>์ฆ๊ฐ€</button>
        </div>
      );
    }
    
  2. ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์ง€์›

    • DOM์ด ์—†๋Š” ํ™˜๊ฒฝ(์˜ˆ: React Native)์—์„œ๋„ ๋™์ผํ•œ ๊ฐœ๋… ์ ์šฉ ๊ฐ€๋Šฅ
    • ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ์ง€์›
  3. ๊ฐœ๋ฐœ ๊ฒฝํ—˜ ํ–ฅ์ƒ

    • ์„ ์–ธ์  UI ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฐ€๋Šฅ
    • ์ƒํƒœ ๊ด€๋ฆฌ ๋‹จ์ˆœํ™”

์ตœ์ ํ™” ๊ธฐ๋ฒ•

  1. ์ปดํฌ๋„ŒํŠธ ๋ฉ”๋ชจ์ด์ œ์ด์…˜

    // React.memo๋กœ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง ๋ฐฉ์ง€
    const MemoizedComponent = React.memo(function MyComponent(props) {
      return <div>{props.value}</div>;
    });
    
  2. Hook์„ ํ™œ์šฉํ•œ ์ตœ์ ํ™”

    // useMemo๋กœ ๊ณ„์‚ฐ ๋น„์šฉ์ด ํฐ ๊ฐ’ ๋ฉ”๋ชจ์ด์ œ์ด์…˜
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
    
    // useCallback์œผ๋กœ ํ•จ์ˆ˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜
    const memoizedCallback = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);
    

์ฃผ์˜์‚ฌํ•ญ ๋ฐ ๋ชจ๋ฒ” ์‚ฌ๋ก€

  1. ํ‚ค(Key) ์†์„ฑ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ

    // ์ข‹์€ ์˜ˆ์‹œ
    {
      items.map((item) => <ListItem key={item.id} {...item} />);
    }
    
  2. ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋Š” ๋ถˆ๋ณ€์„ฑ ์œ ์ง€ํ•˜๊ธฐ

    // ์ž˜๋ชป๋œ ๋ฐฉ๋ฒ•
    const [items, setItems] = useState([]);
    items.push(newItem); //
    
    // ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•
    setItems([...items, newItem]); //
    
  3. ํฐ ๋ฆฌ์ŠคํŠธ๋Š” ๊ฐ€์ƒํ™” ์‚ฌ์šฉํ•˜๊ธฐ

    • react-window๋‚˜ react-virtualized ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ™œ์šฉ

๊ฒฐ๋ก 

Virtual DOM์€ React์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋กœ, ๋ณต์žกํ•œ UI ์—…๋ฐ์ดํŠธ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” ๋งˆ๋ฒ•์ด ์•„๋‹ˆ๋ฉฐ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ ์ ˆํ•œ ์ตœ์ ํ™” ๊ธฐ๋ฒ•์„ ์ ์šฉํ•  ๋•Œ ๊ฐ€์žฅ ํšจ๊ณผ์ ์œผ๋กœ ์ž‘๋™ํ•œ๋‹ค.