[TIL - 2022.9.28] Virtual DOM, Diffing Algorithm, useMemo & useCallback

Jeong Ha Seung·2022년 9월 28일
0

부트캠프

목록 보기
44/51

오늘 공부한 내용

Virtual DOM

먼저 DOM 구조를 한번 살펴보면

출처 : https://dev.to/swarnaliroy94/introduction-to-react-real-dom-virtual-dom-363

이 같은 구조에서 변경이나 삭제를 하는 과정을 거치게 된다면 브라우저가 리플로우리페인트에 해당하는 재연산을 해야된다. 이 과정이 많아지게 된다면 결국에는 브라우저 속도가 느려지게 된다.

하나의 요소만 바꾸려고 해도 전체 요소가 다 리렌더링되기 때문에 그에 대한 비용도 더 많이 든다.

출처 : https://dev.to/iamusj/what-is-the-virtual-dom-2e0a

리액트에서는 virtual DOM을 이용해서 이전과 현재 간의 차이를 비교해서 변경된 부분이 있으면 그 부분만 실제 DOM에 반영하게 된다.

Diffing Algorithms

React는 트리 구조를 이용하며, 레벨 순회 방식으로 탐색을 한다.

자식 엘리먼트의 재귀적 처리

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li> // third 추가
</ul>

이런식으로 third가 추가됐다고 하면 React에서는 first,second는 그대로 된다는 것을 인지하지 못하고 싹 다 리렌더링하게 된다.

알고리즘에서 배열보다 linkedList가 조금 더 좋다는게 이러한 이유인거 같기도 하다.

보통 ul,li 태그를 사용하면서 이러한 에러를 마주치는 것도 이 때문이다.

key

<ul>
  <li key="1">first</li>
  <li key="2">second</li>
</ul>

<ul>
  <li key="1">first</li>
  <li key="2">second</li>
  <li key="3">third</li> // third 추가
</ul>

이렇게 형제 간에서 유니크한 key 값을 부여하게 되면 전체가 리렌더링 되는 것을 막아줄 수 있다.

다만 index를 key로 사용하게 되면 index는 그대로지만 해당 요소가 바뀌게 되면 전체 요소가 바뀌었다고 인지하고 새로운 DOM 트리를 만들어버리기 때문에 비효율적으로 동작한다.

보통 map 을 쓸 때 key로 index를 권장하지 않는 것도 그 이유다.

useMemo

특정한 value를 재사용하고자 할 때 쓰는 Hook

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

출처 : 공식문서

Hook 이름 그대로 Memoization 기법을 이용해서 기존에 했던 연산 결과를 메모리에 저장해두고 나중에 재활용한다.

useCallback

useMemo와 달리 함수를 재사용하는 Hook

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

useMemo vs useCallback

useMemo의 경우에는 deps에 있는 값이 변경되면 콜백을 통해 해당 함수가 실행되고
useCallback의 경우 deps에 있는 값이 변경되면 해당 함수를 반환한다.

참고 자료 : https://basemenks.tistory.com/238

profile
블로그 이전했습니다. https://nextjs-blog-haseungdev.vercel.app/

0개의 댓글