[VueJS] v-memo : 특정 요소가 변경될 때만 렌더링 하기 (메모이제이션)
v-memo
VueJS의 전체적인 버전들이 3.x로 변경되어가는 현재 나중을 위해 변화에 적응해보고자 시간이 날 때마다 공식문서를 뒤적거리던 와중에 v-memo라는 게 Deriectives의 하나로 추가되어있는 것을 발견했다.
굉장히 흥미로운 지시어이지만 안타깝게도 현재 사용하는 Vue 버전이 3.2이상이 아니라면 사용할 수 없다.
내가 왜 v-memo라는 지시어를 흥미롭게 보냐면 React에서 React.memo, useMemo, useCallback라는 리렌더링을 방지하기 위해 메모이제이션을 사용하는 훅들이 존재했기 때문이다.
여기서 메모이제이션을 사용하게 되면 동일한 입력이 주어졌을 경우 재평가하지 않고 함수가 동일한 값을 반환하도록 하여 성능을 위해 프로그램을 최적화하는 기술이라고 할 수 있다.
예를 한번 들어보자.
<div v-memo="[valueA, valueB]">
...
</div>
이런 식으로 v-memo를 사용할 경우, 만약 valueA와 valueB 둘 다 이전과 값이 동일하다면 이 구성요소 div와 div의 하위 요소는 업데이트를 스킵하게 된다. (하위 트리의 메모된 복사본을 재사용할 수 있기 때문에 가상 DOM VNode 생성도 건너뛴다고 한다.)
즉, 데이터가 변경됐을 때 재 렌더링 되는 과정에서 저 v-memo를 사용한 부분만 재 렌더링에 포함시키지 않는 것이다.
다만 valueA와 valueB가 변경됐을 때는 렌더링을 실시한다.
여기서 하나 재미난점은 만약 v-memo="[]" 이런 식으로 빈 배열을 넣어준다면 기능적으로 v-once와 동일하니 올바르게 지정해서 사용하는 것을 권장한다.
여기까지 설명을 들었을 때는 성능상 너무 좋을 것 같기는 한데,
공식문서에서는 특별한 경우가 아니면 굳이 사용할 필요가 없다고 설명하고 있다.
v-for문 사용하며, v-for문에서 반복 횟수가 1000회가 넘을 때(length > 1000) v-memo를 사용하면 아주 좋다고 한다.
공식 문서의 예제를 한번 살펴보자.
<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
<p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>
<p>...more child nodes</p>
</div>
공식문서에서는 위 코드에서 v-memo는 "저 selected의 상태 즉, 값이 변경되면 선택되지 않은 항목에서 선택 항목으로 바뀌거나 그 반대인 경우에만 이 항목을 업데이트하시오"라는 의미를 가지고 있다고 한다.
이럴 경우에는 저 반복을 통해 나온 수많은 값들 중에서 selected 값 변경에 따라 true에서 false로 false에서 true로 변경된 항목들만 업데이트가 되며, 나머지는 재사용을 통해 스킵한다는 의미로 보인다.
여기서 하나 이해가 안 됐던 부분은 첫 번째 예제에서 변경 대상이 되는 데이터 valueA와 valueB를 지정해줬는데, 여기서는 단지 true/false만으로 처리를 하기 때문이다.
(사실 크게 중요하지 않은지 찾아봐도 뭔가 나오는 건 없었다.)
그냥 저러한 표현식으로도 v-memo를 사용할 수 있구나 정도로만 알아두면 될 것 같다.
아 그리고 v-for문과 v-memo를 같이 사용할 경우 하나 주의할 점이 있다.
v-memo와 v-for를 같이 사용하는 경우 동일한 요소에서 사용되는지 확인하십시오.
v-for문 내부에서 v-memo는 작동하지 않습니다.
그냥 v-for문과 같은 태그에 v-memo를 사용하라는 얘기이다.
v-memo는 개발이 끝나고 나중에 성능을 신경 쓸 때나 도입하는 걸로 고민을 해보는 게 좋을 듯하다.
1000개 이상의 목록을 제어하는 경우가 많지는 않을 테니 말이다.
참고: https://vuejs.org/api/built-in-directives.html#v-memo
참고: https://intrepidgeeks.com/tutorial/vue3-please-explain-the-vmome-added-in-2