최적화?
성능 최적화를 왜 할까?
-> 불필요한 렌더링을 방지하기 위해서
소규모 프로젝트에서는 큰 손실이 없을지 모르지만 프로젝트가 커질수록
쓸모없는 렌더링이 메모리를 사용해 속도를 느리게 만들것이고 사용자 경험에도 영향을 미치게 됨
개념
"리액트의 최적화" = "렌더링을 최적화 하는것"
렌더링 개념
리액트에서 컴포넌트가 렌더링을 언제 수행하나?
1. Props가 변경될때
2. State가 변경될때
3. forceUpdate() 를 실행했을때
4. 부모 컴포넌트가 렌더링 되었을때 자식 컴포넌트도 렌더링됨
*참고 :렌더링 과정에서 변수나 함수는 초기화 된다.
React.memo(), useCallback, usememo 모두 memoization 개념 사용
? Memoization
비용이 많이 드는 함수 호출의 결과를 저장하고 동일한 입력이 다시 발생 할 때
캐시된 결과를 반환하여 프로그램의 속도를 높이는데 주로 사용되는 최적화 기술
React.memo()
자신의 props가 바뀔 때만 리렌더링 되는 고차 컴포넌트를 반환하는 함수
* 고차 컴포넌트: 컴포넌트를 받아 새 컴포넌트를 반환하는 함수
컴포넌트가 동일한 props로 동일한 결과를 렌더링 하면
React.memo는 마지막으로 렌더링 된 결과를 재사용
const MyComponent = React.memo(function MyComponent(props) {
/* props를 사용하여 렌더링 */
});
function MyComponent(props) {
/* props를 사용하여 렌더링 */
}
function areEqual(prevProps, nextProps) {
/*
nextProps가 prevProps와 동일한 값을 가지면 true를 반환하고, 그렇지 않다면 false를 반환
*/
}
export default React.memo(MyComponent, areEqual);
useCallback
"함수"를 기억하고 재사용한다.
리랜더링시 재생성 되는 함수
하지만 useCallback을 사용해서 콜백함수를 메모리에 저장하고 재사용 할 수 있다.
React.memo() 를 통해서 컴포넌트의 성능을 높여줬다면
함수에는 메모이제이션된 함수를 반환하는 함수인 useCallback을 적용시켜줌
const List = React.memo(({posts}) => {
console.log("List component is randering")
return (
<ul>
{posts.map(post => {
return(
<ListItem key={post.id} post={post}/>
)
})}
</ul>
)
})
const B = ({message, posts}) => {
console.log("B component is randering")
const testFunction =() => {}
return (
<div>
<h1>B Component</h1>
<Message message={message}/>
<List posts={posts} testFunction={testFunction}/>
</div>
)
}
export default B
이렇게 하면 B컴포넌트가 재랜더링 될 때,
자식 컴포넌트인 List에 props로 내려주는게 있기 때문에 (posts, testFunction)
List까지 계속 재랜더링 되게 됨
const testFunction = () => {
useCallback(() => {}, [])
}
// useCallback으로 감싸준 후 첫번째 인수에 콜백 함수
// 두번째 인수에 의존성 배열 []
의존성 배열 내부 값이 변경 되면 testFunction은 새로 만들어진 함수 객체로 초기화
그렇지 않으면, 동일한 함수 리턴
자식 컴포넌트에 useCallback을 사용하면
계속 자식 컴포넌트가 리랜더링 되는 상황을 막을 수 있음
useMemo
"값"을 기억한다.
component는 state가 변하면 리렌더링을 한다.
값이 변경되지 않았는데 리렌더링 되는 것은 불필요하기 때문에 useMemo를 통해 최적화 할 수 있음
function Component({a, b}) {
const result = compute(a, b)
return <div>{result}</div>
}
Component내의 compute 함수가 만약 복잡한 연산을 수행하면
결과 값을 리턴하는데 오랜시간이 걸림
▶ 이때, 컴포넌트가 계속 리랜더링 되면 연산을 계속 수행하는데 오랜시간이 걸려서
성능에 안좋은 영향을 미치게 되고 UI 지연 현상도 일어나게 됨
❗️ 이런 현상을 useMemo로 해결!
compute 함수에 넘겨주는 a, b의 값이 이전과 동일하면,
컴포넌트가 리랜더링 되더라도 연산을 다시 하지 않고 이전 랜더링 때 저장해두었던 값 재활용
function Component({a, b}) {
const result = useMemo(() => {compute(a, b)}, [a, b])
return <div>{result}</div>
}
// useMemo로 감싸주고 첫번째 인수에 콜백 함수
// 두번째 인수로 의존성 배열
의존성 배열 안에 있는 값이 업데이트 될 때만 콜백 함수를 다시 호출하여
메모리에 저장된 값을 업데이트
function Component({a, b}) {
const result = useMemo(() => {compute(a, b)}, [])
return <div>{result}</div>
}
만약 두번째 인수에 빈 배열을 넣는다면
마운트 될 때만 값을 계산하고 그 이후론 계속 메모이징 된 값을 꺼내와 사용
'📚 프론트엔드 공부 일지 > REACT' 카테고리의 다른 글
이미지 레이지 로딩 (0) | 2024.07.30 |
---|---|
vite를 이용한 리액트 생성 (1) | 2024.07.26 |
React 확장 프로그램 / Profiler 성능 측정 프로그램 (6) | 2024.07.24 |
React Hooks (0) | 2024.07.19 |
constructor / super (0) | 2024.07.18 |