메모이징 액기스 자문자답

pengooseDev·2023년 2월 13일
1
post-thumbnail

1

부모 컴포넌트가 re-rendering되면 자식 컴포넌트의 값이 변하지 않았음에도 불구하고 렌더링이 된다. 왜 그런가?

부모 컴포넌트(함수)가 호출되면 내부에서 자식 컴포넌트(함수)를 호출하여 자식 컴포넌트가 return하는 것이 V-Dom. 즉, 객체(참조 데이터 타입)이라는 점에 기인한다.

함수가 return하는 V-Dom(객체)의 정보는 이전과 값이 같더라도, 참조 데이터의 특성상 새로운 Heap Memory에 주소에 할당한다. 따라서 JS엔진은 자식 컴포넌트가 return한 객체를 이전과 다른 데이터라고 판단하고 re-render를 발생시킨다.

즉, "메모리 주소가 변했니?"가 관건이라는 것이다.
React.memo()는 함수 컴포넌트가 객체를 return하는 순수함수라는 점을 이용한 메모이제이션이다. 함수 컴포넌트의 매개변수가 힙메모리에 메모이징 되어있다면, 함수 컴포넌트를 실행하지 않고 이전 메모리 주소를 그대로 참조한다.

보편적으로 많이 묻는 질문이지만, 사실 위 질문이 조금 마음에 들지 않았다. ReactJS라는 것은 사실 문법적 설탕에 불과하며, 결국 JS엔진 위에서 돌아가는 JS코드이다.

부모 컴포넌트의 re-render를 자식 컴포넌트의 re-render을 발생이라는 질문 자체가 근본적인 원인으로 접근하지 않는다. 즉, ReactJS를 JS로 바라보는 것이 아닌, ReactJS 그 자체의 문법이 가진 인과관계라고 착각하게 만들 수 있다는 것이다.

부모 컴포넌트가 호출되면 발생하는 일을 V-Dom과 JS엔진을 이용해 설명하고, 이를 토대로 자식 컴포넌트가 다시 렌더링 될 수 밖에 없는 이유, 이를 해결하기 위한 메모이징이 어떻게 구현되어있는지를 설명해주세요.

길긴 하지만 위의 표현이 조금 더 나은 표현이 아닐까 싶다.


2

자식 컴포넌트에 React.memo를 걸어주고, props로 넘겨주는 콜백함수를 넘겨준 경우, 자식 컴포넌트의 값과 콜백함수가 변하지 않았음에도 불구하고 re-rendering이 발생한다. 왜 그런가?

부모 컴포넌트에서 넘겨주는 콜백함수가 원인이다. 함수 또한 객체(일급 객체)이다. 즉, 함수 내부의 코드가 이전과 동일하더라도 함수가 저장되는 힙 메모리의 주소는 이전과 달라진다. 자식 컴포넌트 입장에선 함수 컴포넌트(순수함수) 내부로 들어오는 매개변수(콜백함수)의 메모리 주소가 바뀌었기 때문에 값이 변했다고 판단한다. 따라서, re-rendering이 발생한다. 이런 경우, 자식 컴포넌트에 React.memo()뿐 아니라 부모 컴포넌트에서 넘겨주는 콜백함수를 useCallback()함으로써 부모 컴포넌트가 콜스택에 올라갈 때, 함수 메모리 주소가 바뀌지 않도록 메모이징 해주어야 한다.


3

메모이제이션은 캐시 메모리를 사용하지 않는데, 과연 캐싱으로 볼 수 있는가?

보편적인 표현으로는 캐싱이다. ReactJS의 메모이제이션은 함수 컴포넌트(순수함수) 매개변수를 확인하고, 함수의 실행 여부를 판단한다. 이러한 일련의 과정은 전부 JS의 힙 메모리에서 이루어진다.

보편적인 레벨에선 캐싱은 캐시 메모리의 이용 여부가 중요한 것이 아니다. 캐싱은 재사용되는 데이터나 연산결과를 특정 공간에 저장함으로써 프로세스의 시간을 단축하는 방법론을 일컫는 말이다. 이러한 방법론은 메모리 캐시, 디스크 캐시, 브라우저 캐시, 인메모리 데이터와 같은 분산 캐시뿐 아닐라 프록시 서버에까지 적용되어 프록시 캐싱과 같이 광범위적으로 적용되는 방법론이라는 것을 알 수 있다.
즉, ReactJS의 메모이제이션은 캐시 메모리를 사용하지 않고, Heap 메모리에서만 진행되지만, 엄연한 캐싱이라고 볼 수 있다.

하지만, 기술적 레벨에서 깊게 생각해본다면, 캐싱이 아니라 캐싱을 힙메모리에서 구현한 모방기술일 뿐, 캐싱이 아니라고 생각한다.

"캐싱"의 기원은 결국 자주 사용하는 값을 가져오기위해 계속 하드에 접근하기보다, 이를 캐시 메모리에 저장하고 사용하여 시간을 단축하는 것을 뜻하기 때문이다. 시간이 지나며 점점 다양한 분야에서 캐싱이라는 단어가 사용되고 있지만, "기술적 레벨"의 엄밀한 정의에 따르면 캐싱으로는 보기 어렵다는 것이 나의 관점**이다. (물론, 보편적인 표현으로는 캐싱이 맞다는 입장이다.)

0개의 댓글