성능최적화
- 많은 데이터 렌더링
- 개발자도구로 성능 모니터링
- React.memo 컴포넌트 리렌더링 성능 최적화
- onToggle, onRemove가 새로워지는 현상 방지
- react-virtualized를 사용한 렌더링 최적화
* 컴포넌트 리렌더링되는 상황
(1) 자신이 전달받은 props가 변경될 때
(2) 자신의 state가 바뀔 때
(3) 부모 컴포넌트가 리렌더링 될 때
(4) forceUpdate함수가 실행 될 때
* 컴포넌트 리렌더링 성능을 최적화해주는 작업을 해줘야한다.
* 리렌더링이 불필요할 떄는 리렌더링을 방지해줘야 한다, 어떻게??
- shouldComponentUpdate 라이프사이클 사용하면 된다.
- 함수컴포넌트에서는 : React.memo 사용, 컴포넌트의 props가 바뀌지 않았다면, 리렌더링 하지 않도록 설정하여 함수 컴포넌트의 리렌더링 성능을 최적화할 수 있다.
import React from 'react';
const TodoListItem = ( {todo, onRemove, onToggle} ) => {
(...)
};
export default React.memo(TodoListItem);
- 이렇게하면, TodoListItem 컴포넌트는 todo, onRemove, onToggle이 바뀌지 않으면 리렌더링하지 않음 (우🫢와)
- 현 프로젝트에서는, todos배열이 업데이트되면 onRemove와 onToggle함수도 새롭게 바뀐다. onRemove와 onToggle함수는 배열상태를 업데이트하는 과정에서 최신상태의 todos를 참조하기 때문에 todos배열이 바뀔 때마다 함수가 새로 만들어진다. 이걸 방지하기 위해서는,
(1) useState의 함수형 업데이트 기능을 사용하는 것,
(2) useReducer를 사용하는 것
(1) useState의 함수형 업데이트
- 기존 setTodos 함수 사용할 때는 새로운 상태를 파라미터로 넣어줬는데 그 대신에, 상태업데이트를 어떻게 할지 정의해주는 업데이트함수를 넣을 수도 있다. 이를 `함수형업데이트` 라고 함.
const [number, setNumber] = useState(0);
const onIncrease = useCallback(() => setNumber(prevNumber + 1), []);
- 기존 데이털르 수정할 때 직접 수정하지 않고, 새로운 배열을 만든 후에 새로운 객체를 만들어서 필요한 부분을 교체해주는 방식
- '불변성을 지킨다'
- 불변성이 지켜지지 않으면 객체 내부값이 새로워져도 바뀐 것을 감지하지 못한다.
- 전개연산자(...문법)을 사용하여 객체나 배열 내부의 값을 복사할 때는 shallow copy를 하게 됨.
- 즉, 내부값이 완전히 새로 복사되는 것이 아니라 가장 바깥쪽 값만 복사된다.
- 따라서, 내부 값이 객체 혹은 배열이라면 내부값 또한 따로 복사해줘야함.
const todos = [
{
id: 1,
checked: true
},
{
id: 2,
checked: true
}
];
const nextTodos = [...todos];
nextTodos[0].checked = false;
console.log(todos[0] === nextTodos[0]);
nextTodos[0] = {
...nextTodos[0],
checked: false
};
console.log(todos[0] === nextTodos[0]);
- 만약, 객체 안에 있는 객체라면 불변성을 지키면서 새 값을 할당해야 하므로 다르게 해줘야 한다.
const nextComplexObject = {
...complexObject,
objectInside: {
...complexObject.objectInside,
enabled: false
}
};
console.log(complexObject === nextComplexObject);
console.log(complexObject.objextInside === nextComplexObject.objectInside);