그 어떤 개발을 할 때에 최적화 라는 것은 필수 요소이다. React에서는 렌더링 최적화를 위한 설정과 기능들을 제공하고 있는데, https://blog.bitsrc.io/10-ways-to-optimize-your-react-apps-performance-e5e437c9abce 을 참고하여 React의 렌더링 최적화를 공부하며 정리한다.
List를 구현할 때, List 내부의 서버에서 받아오는 데이터가 많으면 초기 렌더링 시에 성능이 저하가 된다. 따라서 이와 같은 경우에는 1페이지 10개 출력, 2페이지 10개 출력과 같이 페이지별 관리를 하여 최적화 할 수 있다. 하지만 이와 같은 페이지별 관리는 서버에서의 작업이 필요하다. 10개만 요청했을 때, 서버가 10개만 response를 해줘야 하기 때문이다.
이와 같은 상황에 대중적으로 사용되고 있는 react-window 라이브러리가 있다. 이 라이브러리를 사용하면 리스트를 출력할 때 보이는 부분만 렌더링되고, 스크롤을 내릴 시에 차례로 리스트를 렌더링할 수 있다.
shouldComponentUpdate() 는 클래스형 컴포넌트의 리렌더링 시에 조건을 걸 수 있는 함수이다. React는 상태 변화가 있을 시에 Updating lifecycle이 돌며 리렌더링 하게 된다. 컴포넌트의 트리 구조가 부모-자식의 구조를 가질 때, 부모의 값이 변경되면 자동으로 자식도 리렌더링 하게 되는데, 이런 상황에 불필요한 자식 컴포넌트의 렌더링을 방지하기 위해 shouldComponentUpdate()를 사용한다.
shouldComponentUpdate()는 매개변수로 변화되는 props와 state 값을 받는다. 이 값을 가지고 조건을 걸어, 리렌더링을 방지할 수 있다.
shouldComponentUpdate()가 false를 반환하면 render()는 호출되지 않는다.
shouldComponentUpdate(nextProps, nextState) {
if(nextState.data === this.state.data) {
return false;
} else {
return true;
}
}
React의 클래스형 컴포넌트에서는 shouldComponentUpdate()과 비슷한 역할을 하는 React.PureComponent를 제공한다. React.PureComponent는 state와 prop값을 체크하여 component가 업데이트 되어야 하는지 확인한다.
React.PureComponent 는 클래스형 컴포넌트에서 extends로 상속받는 부분을 변경해주면 된다.
class Pure extends React.PureComponent<PureProps, PureStates> {
constructor(props: AuthProps) {
super(props);
this.state = {};
}
render() {
return (
<div> React.PureComponent </div>
);
}
}
Lazy Loading는 부하를 단축하기 위해 자주 사용되는 최적화 기법 중 하나로, 의미는 필요 시점까지 객체의 초기화를 연기시키는 것을 의미한다. 프로젝트가 커질수록 번들링 시 크기가 커지게 되는데, 이를 방지하기 위한 방법으로 번들을 나누는 방법을 사용한다. 그렇기에 Code Spliting을 하게 되는데, 이 Code Spliting은 Lazy Loading을 통한다. 많은 코드의 양을 코드를 수정하지 않고, Lazy Loading을 통하여 필요하지 않는 부분을 불러오지 않게 하여 최적화한다.
React에서는 자체적으로 React.lazy나 React.suspense로 Lazy Loading 기능을 제공해주지만, 이 두 기능은 아직 서버 사이드 렌더링 (Server-Side Rendering)을 지원하지 않기 때문에 Loadable Components의 사용을 추천한다.
/* Asynchronous app components for lazy-load */
const AsyncHomeComponent = Loadable({
loader: () => import(/* webpackChunkName: "home" */ './Home'),
loading: LoadingPage
});
...
...
<Switch>
<Route
path='/home'
component={AsyncHomeComponent}
exact
/>
</Switch>