Thief of Wealth

기존 문제점

 

리액트는 DOM 노드의 자식들을 재귀적으로 처리할 때 기본적으로 동시에 두 리스트를 순회하고 차이점이 있으면 변경한다.

 

ex)

<ul>
	<li>1</li>
    <li>2</li>
</ul>

to

<ul>
	<li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

위 코드로 변경하는 경우

리액트는 2개의 트리에서 

<li>1</li> 가 일치하는 것을 확인하고

<li>2</li> 가 일치하는 것을 확인하고
<li>3</li>가 다르므로, 트리에 추가한다.

즉, 1,2번째 엘리먼트가 똑같고 마지막 엘리먼트만 다르므로 모든 자식 노드를 새로 그릴 필요 없이, 변경된 사항만 새롭게 그리게 된다.

 

 

하지만 아래의 경우에는 리스트의 맨 앞에 엘리먼트를 추가하는 경우 성능이 좋지 않다.

 

<ul>
	<li>1</li>
    <li>2</li>
</ul>

to

<ul>
    <li>3</li>
	<li>1</li>
    <li>2</li>
</ul>

 

왜냐하면 새로운 엘리먼트가 첫번째로 생겼기 때문에 리액트가 모든 요소가 제자리에 위치하지 않았다고 판단하고,

모든 자식 엘리먼트를 새로그리기 때문이다. (성능이슈 유발)

 

 

해결책

각 자식들이 key를 가지고 있게하여, 기존 트리와 이후 트리의 자식들이 일치하는지 확인하게 한다.

<ul>
  <li key="a">1</li>
  <li key="b">2</li>
</ul>

to

<ul>
  <li key="c">3</li>
  <li key="b">2</li>
  <li key="a">1</li>
</ul>

위 예시같은 경우에는 key값이 c을 가지는 요소가 새로 추가되었고 a과 b는 그저 이동만 하면됨을 알 수 있으므로,

모든 요소를 제거하고 새로 생성하는 것보다는 효율적으로 동작하게 만들 수 있음을 뜻한다.

 

+ key는 형제 레벨사이에서만 unique하면 된다.

+ 배열의 index를 key로 사용하는 것도 괜찮지만, 재배열되는 경우에는 기존 key값이 달라져야 하므로 비효율적으로 동작할 수 있다.

profile on loading

Loading...