리액트 최적화 요약집 (useCallback, useMemo ...)
1. 리액트 최적화란 무슨 뜻일까?
- 최적화란 프로그램 변현 기술로 코드를 이용하여 CPU, 메모리의 리소스가 적게 소모시키며 속도도 향상해주도록 하는 것
- 리액트 최적화는 리액트 기술을 활용하여 관련 코드를 이용한 성능 개선을 시켜준다고 볼 수 있다.
2. 데이터를 업데이트 하는 과정에서 불변성을 지켜야 되는데 그 이유는?
- 자식 컴포넌트에 부모 컴포넌트에서 해당 데이터가 생기거나 할 경우 자식 컴포넌트까지 렌더링이 된다
- 이런 상황은 Virtual DOM에만 리렌더링을 해주어 큰 문제가 일어나지 않는다.
하지만 최악의 조건인 상황이나 관련 데이터들이 한 번에 수백 개씩 혹은 그 이상이라면 성능 손실이 발생하며
이는 렌더링에서 수행하는 로직이 많을수록, 많은 컴포넌트를 출력할수록 손실을 커질 것임.
3. 리액트에서는 렌더링이 되는 대표적인 조건
1. state 변경이 있을 때
2. 부모 컴포넌트가 렌더링 될 때
3. 새로운 props이 들어올 때
4. shouldComponentUpdate에서 true가 반환될 때
5. forceUpdate가 실행될 때
- 여기서 1번과 2번은 얕은 비교를 통해 새로운 값인지 여부를 따져 리렌더링을 한다
- 클래스 컴포넌트에서는 렌더링이 될 경우, render 메서드만 리 렌더링이 되지만,
함수형 컴포넌트(hooks)에서는 위 조건 중에 하나라도 될 경우 함수 전체가 재실행
4. 위 문제를 해결할 수 있는 useMemo와 useCallback
useMemo
- 복잡한 함수 결괏값을 기억 (함수의 리턴값을 기억)
useRef는 일반 값을 기억
- 사용하는 이유
useCallback 사용만으로는 하위 컴포넌트의 리렌더를 막을 수 없음
하위 컴포넌트가 참조 동일성에, 의존적인, 최적화된 Purecomponent 이어야만
비로소 불필요한 리 렌더링을 막을 모든 것이 완성됨.
- 사용법
- 고차 컴포넌트이므로 사용 중인 component를 memo로 감싸주기만 하면 됨.
- props에 대해 기본으로 제공되는 얕은 비교가 아닌 커스텀을 하고 싶다면
두 번째 인자로 비교 함수를 넣어 사용할 수 있음
useMemo는 메모리제이션된 값을 반환한다 (리액트 공식 문서)
useCallback
- 함수 자체를 기억하고 있음
- 의존성에 포함된 값이 변경되지 않는다면 이전에 생성한 함수 참조 값을 반환해줌
- 사용하는 이유
현재 하위 컴포넌트에 전달하는 콜백 함수를 inline 함수로 사용하고 있다거나,
컴포넌트 내에서 함수를 생성하고 있다면 (프로그래밍 구동에는 문제가 없겠지만)
새로운 함수 참조 값을 계속해서 만들고 있는 것!!!
- 사용법
- 인라인 콜백과 그것의 의존성 값의 배열을 전달
useCallback은 콜백의 메모이제이션된 버전을 반환할 것임.
그 메모이제이션된 버전은 콜백의 의존성이 변경되었을 때에만 변경됨.
- 자식컴포넌트에 함수를 넘길 때 무조건 useCallback를 적용시켜줘야 한다.
자식 입장에서는 부모가 매번 새로운 함수를 주는 것이라고 판단한다 고 한다.
useCallback의 동작방식
useEffect에서 제2의 인자로 의존성 배열 안에 값이 존재할 경우
=> componentDidUpdate
useEffect에서 제2의 인자로 의존성 배열로 빈 배열로 존재할 경우
=> componentDidMount
useCallback는 메모리제이션된 함수를 반환한다 (리액트 공식 문서)
- 주의해야할 점
- 함수 생성자체가 비용이 클 경우, 클릭 이벤트처럼 여러 번 누를 경우에
기억을 잘해서 처음 찍혔단 값을 계속 가지고 있는다.
그래서 두번째 인자에 배열 안으로 같이 넣어줘야. (useEffect와 유사 방식)
- useMemo, useCallback, useEffect가 2번째 인자가 중요하다
(어느 시점에 실행이 될지 정해주기 때문!)
느낀점
- 항상 함수형 컴포넌트(hooks)만 쓰니
class형 컴포넌트의 componentDidMount나 componentDidUpdate를 볼때마다
무슨 의미를 뜻하는 지 몰랐는데 이 정리 잘되어 있는 블로그를 보면서 많은 정리를 할 수 있었던 것 같다!
그리고 존재만 알았던 useMemo와 useCallback의 특징도 알 수 있었던 글이라 좋았다!
참고 링크
리액트 최적화 요약집 (useCallback, useMemo ...)
1. 리액트 최적화란 무슨 뜻일까?
2. 데이터를 업데이트 하는 과정에서 불변성을 지켜야 되는데 그 이유는?
하지만 최악의 조건인 상황이나 관련 데이터들이 한 번에 수백 개씩 혹은 그 이상이라면 성능 손실이 발생하며
이는 렌더링에서 수행하는 로직이 많을수록, 많은 컴포넌트를 출력할수록 손실을 커질 것임.
3. 리액트에서는 렌더링이 되는 대표적인 조건
함수형 컴포넌트(hooks)에서는 위 조건 중에 하나라도 될 경우 함수 전체가 재실행
4. 위 문제를 해결할 수 있는
useMemo와useCallbackuseMemouseRef는 일반 값을 기억useCallback 사용만으로는 하위 컴포넌트의 리렌더를 막을 수 없음
하위 컴포넌트가 참조 동일성에, 의존적인, 최적화된 Purecomponent 이어야만
비로소 불필요한 리 렌더링을 막을 모든 것이 완성됨.
두 번째 인자로 비교 함수를 넣어 사용할 수 있음
useCallback현재 하위 컴포넌트에 전달하는 콜백 함수를 inline 함수로 사용하고 있다거나,
컴포넌트 내에서 함수를 생성하고 있다면 (프로그래밍 구동에는 문제가 없겠지만)
새로운 함수 참조 값을 계속해서 만들고 있는 것!!!
useCallback은 콜백의 메모이제이션된 버전을 반환할 것임.
그 메모이제이션된 버전은 콜백의 의존성이 변경되었을 때에만 변경됨.
자식 입장에서는 부모가 매번 새로운 함수를 주는 것이라고 판단한다 고 한다.
useCallback의 동작방식useEffect와 동작방식이 유사함!기억을 잘해서 처음 찍혔단 값을 계속 가지고 있는다.
그래서 두번째 인자에 배열 안으로 같이 넣어줘야. (useEffect와 유사 방식)
(어느 시점에 실행이 될지 정해주기 때문!)
느낀점
class형 컴포넌트의
componentDidMount나componentDidUpdate를 볼때마다무슨 의미를 뜻하는 지 몰랐는데 이 정리 잘되어 있는 블로그를 보면서 많은 정리를 할 수 있었던 것 같다!
그리고 존재만 알았던
useMemo와useCallback의 특징도 알 수 있었던 글이라 좋았다!참고 링크