useMemo는 컴포넌트 성능을 최적화하는 방법 중 하나이다.
useMemo에서 메모(Memo)는 memoization을 의미한다.
memoization은 메모리에 넣기
라는 뜻이다.
메모이제이션이란, 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때 이전에 계산한 값을 메모리에 저장함으로써 동일한 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술이다.
예를 들면, 어떤 숫자를 리턴하는 함수를 반복적으로 호출할 때 맨 처음 이 함수를 호출했을 때 계산된 값을 메모리에 저장해놓고 또 같은 함수를 호출했을 때 그때마다 다시 계산하지 않고 이미 저장되어 있는 값을 꺼내서 쓰는 것이다.
자주 필요한 값을 맨 처음 필요할 때 캐싱을 해두어 값이 필요할 때마다 다시 계산하지 않고 캐시에서 꺼내서 사용한다는 의미이다.
캐시(cache)란?
데이터나 값을 미리 복사해놓는 임시 장소를 가리킨다.
리액트에서 함수형 컴포넌트는 '함수'이기 때문에 렌더링 될 때 호출된다. 또, 호출될 때마다 함수 내부의 모든 내부 변수가 초기화된다.
리액트는 state, props의 변화가 생기면 렌더링이 자주 발생하게 된다. 컴포넌트가 렌더링될 때마다 함수 내부의 변수는 초기화되기 때문에 이 변수가 어떠한 함수의 리턴값을 받는 변수라면 렌더링 될 때마다 변수가 초기화되면서 함수도 반복적으로 호출될 것이다.
만약, 호출하는 함수가 오래 걸리는 작업을 하는 함수라고 가정한다면 렌더링 될 때마다 초기화되는 변수로 인해 이 무거운 함수를 계속 호출하기 때문에 성능이슈가 생길 수 있고 비효율적일 것이다.
같은 값을 반복적으로 할당할 뿐인데 무거운 작업을 계속 반복해야 한다면 굉장히 비효율적이기 때문에 이때 useMemo
를 사용해서 이러한 성능이슈를 해결할 수 있다.
useMemo는 처음 함수를 호출했을 때 계산된 결과값을 메모리에 저장해서 컴포넌트가 리렌더링되더라도 같은 함수를 또 호출하지 않고 이전에 계산된 값을 메모리에서 꺼내서 재사용
하도록 한다.
const 함수_리턴값을_받을_변수 = useMemo(()=>{
return 함수();
}, [ 배열 ]);
useMemo는 첫번째 인자로 콜백함수, 두번째 인자로 배열을 받는다.
useMemo로 전달된 함수는 렌더링 중에 실행된다.
렌더링 중에 하지 않는 것은 useMemo에서 하지 않아야 한다.
첫번째 인자 콜백함수는 메모이제이션이 필요한 함수를 계산해서 리턴해준다.
이 콜백함수에서 return한 값이 useMemo가 리턴하는 값이 된다.
두번째 인자는 의존성 배열이라고도 불리는데, 이 배열안의 값이 업데이트 될 때만 콜백함수를 다시 호출해서 메모이제이션된 값을 업데이트해서 다시 메모이제이션 해준다.
두번째 인자에 빈 배열을 넘기는 경우, 처음 컴포넌트가 마운트되었을 때만 값을 계산하고 이후에는 업데이트없이 계속 메모이제이션된 값을 꺼내서 사용한다.
두번째 인자인 배열을 생략하는 경우 매 렌더링마다 새로운 값을 계산한다.
하지만, 무분별하게 useMemo를 사용하면 성능이슈가 생길 수 있다.
불필요한 값까지 useMemo로 사용해서 메모이제이션하면 오히려 성능에 문제가 생길 수 있다.
참고 자료
React Hooks에 취한다 - useMemo 제대로 사용하기
위키백과 메모이제이션
위키백과 캐시
리액트 공식문서 Hook API 참고서 useMemo