우아한테크코스 미션을 진행하던 도중 아래와 같은 피드백을 받게 되었다.
리뷰어님이 좋은 제안을 해주셨는데 아무 생각 없이 피드백을 반영하기 보다는 useMemo
를 사용했을 때의 유의미한 차이를 확인해보고 싶어 이것저것 찾아보고 정리해보았다.
- useMemo 관련 아티클
Should You Really Use useMemo in React? Let’s Find Out
해당 아티클은 직접 시간복잡도에 따라 useMemo
를 사용했을 때 성능을 비교해보는 실험해보는 글이다.
글을 요약해보면 아래와 같다.
1. useMemo 를 사용하면 초기 렌더링 성능이 악화된다.
2. 시간복잡도가 낮은 연산이면 useMemo 를 사용했을 때 이점이 없다.
3. 시간복잡도가 큰 연산이면 useMemo 를 사용했을 때 초기 렌더링의 성능은 악화되지만 리렌더링 시 연산이 빨라진다.
리액트 공식문서를 읽어보면 위에서 언급한 내용과 비슷한 내용을 확인해볼 수 있었다.
1. useMemo 는 처음 렌더링을 더 빠르게 만들지 않는다.
2. 일반적으로 연산이 큰 경우가 아니면 useMemo로 감싸는 것에 대한 이득이 없다.
3. 모든 코드에 useMemo 를 쓰는 팀도 있지만 그러면 가독성이 떨어진다는 단점이 있다.
해당 내용을 종합해보자면 높은 비용의 연산인 경우에만 useMemo
를 사용하는 게 좋다는 결론이 나온다.
여기서 들었던 생각은 결국 모든 자바스크립트 코드는 바이트 코드 또는 기계어로 컴파일되어 메모리에 적재된 후 CPU에 의해 실행이 된다.
그렇다면 모든 소스코드는 결국 메모리에 저장되는 과정을 거치게 되는데, 저장된 김에 useMemo
를 이용하여 메모리에 저장된 데이터를 재활용하면 무조건 이득이 아닌가? 생각했다.
그래서 내 나름대로 useMemo
가 처리되는 방식을 정리해보며 해당 궁금증을 해결하였다.
1. 브라우저에서 V8 엔진의 JIT 컴파일러를 통해 자바스크립트 코드가 바이트코드 또는 기계어로 컴파일된다.
2. 해당 바이트코드 또는 기계어는 RAM 에 적재된다.
3. RAM 에 적재된 코드는 CPU 에 의해 실행되어 연산을 수행한다.
1. 브라우저에서 V8 엔진의 JIT 컴파일러를 통해 자바스크립트 코드가 바이트코드 또는 기계어로 컴파일된다.
2. 해당 바이트코드 또는 기계어는 RAM 에 적재된다.
3. RAM 에 적재된 코드는 CPU 에 의해 실행된다.
4. useMemo 코드를 실행하며 의존성 배열 값을 메모리에서 읽어온다.
5. 읽어온 useMemo dependency 의 값과 변경된 dependency 의 값을 비교한다.
5-1. 해당 dependency 의 값이 동일한 경우 메모리에 저장되어 있던 데이터 사용한다.
5-2. 해당 dependency 의 값이 동일하지 않으면 해당 연산을 수행한 후 결과를 새로 힙 메모리에 저장한다.
정리를 해보자면 useMemo
를 사용하는 경우 RAM 에서 데이터를 읽는 추가 오버헤드가 발생한다. 그리고 dependency 의 값이 변경되었는지 비교를 한 후 연산이 이뤄지기에 무조건 useMemo 를 사용하는 게 좋다고 볼 수 없다.
컴퓨터의 CPU 처리속도는 매우 빠르다. useMemo
를 사용하게 되면 추가적인 메모리 I/O 오버헤드가 발생하는데 해당 작업 오버헤드보다 CPU 의 연산이 빠르다면 오히려 useMemo
를 사용하는 게 성능이 떨어질 수 있다.
그래서 결론은 공식문서에 적힌 내용처럼..
연산의 비용이 높은 경우에 useMemo 사용을 고려해보고 사용하자!
우아한테크코스에서 희망자에 한해 방과 후 발표를 할 기회가 있어 해당 내용으로 발표를 진행했었다. 발표를 준비하면서 스스로 정리가 안 됐던 부분들도 정리할 수 있었고 해당 내용으로 많은 고민을 하며 메모이제이션 사용에 대한 나만의 기준이 세워졌다.