저번 시간에 이어서 렌더링 최적화에 관련된 이야기를 마무리해보도록 하겠다.
애플리케이션에서 방대한 양의 컴포넌트를 한번에 렌더링하는 것은 당연히 시간 지연의 원인이 될 것이다. 그래서 이번에는 보이지 않는 곳에서 렌더링되는 컴포넌트들의 렌더링을 해당 컴포넌트가 window
에 노출될 때로 미룰 수 있는 react-virtualized
라이브러리를 사용하여 렌더링 최적화를 진행해보려고 한다.
다음 명령어를 통해 yarn
에서 라이브러리를 설치하자.
$yarn add react-virtualized
이제 react-virtualized
에서 제공하는 List
컴포넌트를 이용하여 렌더링 최적화를 진행할 것이다.
해당 라이브러리를 사용하려면 window
상에 보여지는 컴포넌트들의 실제 크기를 px
단위로 계산해야한다는 단점이 존재한다. 물론 이는 크롬 개발자 도구를 사용하여 확인할 수 있지만...반응형을 고려했을 때 scss
나 calc
를 이용해 세밀한 계산식을 명시해주어야 할 것 같다.
그렇게 컴포넌트의 크기를 계산하고 나면, 다음과 같이 코드를 작성하면 된다.
component.js
import React, { useCallback } from 'react';
import { List } from 'react-virtualized';
(...)
(...)
const rowRenderer = useCallback(
({ index, key, style }) => {
const todo = todos[index];
return(
<TodoListItem
todo={todo}
key={key}
onRemove={onRemove}
onToggle={onToggle}
style={style}
/>
);
},
[onRemove, onToggle, todos],
);
return(
<List
className='TodoList'
width={512} // 보여지는 컴포넌트 너비
height={513} // 보여지는 컴포넌트 노ㅍ이
rowCount={todos.length} // 항목 개수
rowHeight={57} // 항목 높이
rowRenderer={rowRenderer} // 항목을 렌더링할 때 쓰는 함수
list={todos} // 배열
style={{ outline: 'none' }} // List에 기본 적용되는 outline 스타일 제거
/>
);
};
export default React.memo(TodoList);
위의 List
에서 신경쓰이는 부분은 rowRenderer
에 대한 것이다.
이 함수는 react-virtualized
에서 각 Todoitem
을 렌더링할 때 사용하며, 이 함수르 List
컴포넌트의 props
로 설정해주어야 한다.
마치 wrapper
로 전체 아이템들을 감싸는 느낌이라고 생각하면 좋을 것 같다.
이때 List
에는 해당 리스트의 전체 크기와 각 항목의 높이, 각 항목을 렌더링할 때 사용할 함수, 그리고 배열을 props로 넣어야 한다. 그러면 List
컴포넌트가 자동으로 최적화를 진행하는 방식이다.
이때, 기존의
TodoList
를 렌더링해서 지정된 스타일이 깨지므로Todoitem
에서style
props를 추가해주어야 함을 잊어서는 안된다!
지금까지 리액트 애플리케이션에서 대량의 데이터를 렌더링할 때 이를 최적화하는 방법에 대하여 알아보았다. 물론 모든 애플리케이션에서 이를 적용할 필요도, 모든 컴포넌트에 일일이 React.memo
를 작성할 필요도 없다. 일반적으로 보여 줄 항목이 100개 이상이고 업데이트가 자주 발생하는 애플리케이션이라면 이러한 방법을 적용해 최적화를 진행하는 것을 고려해야 한다.