프론트엔드 첫걸음

react-virtualized를 사용한 렌더링 최적화 본문

카테고리 없음

react-virtualized를 사용한 렌더링 최적화

차정 2022. 8. 29. 10:37
리액트를 다루는 기술 11장 8절

 

설치 

yarn add react-virtualized 

 

TodoList.js

react-virtualized 사용 전

import React from 'react';
import TodoListItem from './TodoListItem';
import './../css/TodoList.css';
const TodoList = ({ todos, onRemove, onToggle }) => {

    return (
    <div className="TodoList">
      {todos.map((todo) => (
        <TodoListItem
          todo={todo}
          key={todo.id}
          onRemove={onRemove}
          onToggle={onToggle}
        />
      ))}
    </div>
  );
};

export default TodoList;

 

react-virtualized 사용 후

import React, { useCallback } from 'react';
import { List } from 'react-virtualized';
import TodoListItem from './TodoListItem';
import './../css/TodoList.css';
const TodoList = ({ todos, onRemove, onToggle }) => {
  const rowRenderer = useCallback(
    ({ index, key, style }) => {
      const todo = todos[index];
      return (
        <TodoListItem
          todo={todo}
          onRemove={onRemove}
          onToggle={onToggle}
          key={key}
          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' }}
    />
  );
};

export default TodoList;

key 와 style 속성을 추가한 기존 컴포넌트를 반환하는 rowRenderer 함수 작성하고, List컴포넌트에 rowRenderer를 props로 전달한다.
기존 TodoList 컴포넌트는 List 컴포넌트를 반환하며, LIst 컴포넌트는 해당 리스트의 전체크기, 각항목의 높이, 항목개수, rowRenderer함수, lists(배열 객체) 를 props로 가진다.
react-visualized는 List 컴포넌트가 전달받은 props를 사용하여 자동으로 최적화시켜준다.

 

TodoListItem.js

react-virtualized 사용 전

import React from 'react';
import { IoIosRemoveCircleOutline } from 'react-icons/io';
import { MdCheckBoxOutlineBlank, MdOutlineCheckBox } from 'react-icons/md';
import './../css/TodoListItem.css';

const TodoListItem = ({ todo, onRemove, onToggle }) => {
  const { id, text, checked } = todo;
  return (
      <div className="TodoListItem">
        <div
          className={checked ? 'checkbox checked' : 'checkbox'}
          onClick={() => onToggle(id)}
        >
          {checked ? <MdOutlineCheckBox /> : <MdCheckBoxOutlineBlank />}

          <div className="text">{text} </div>
        </div>
        <div className="remove" onClick={() => onRemove(id)}>
          <IoIosRemoveCircleOutline />
        </div>
      </div>
  );
};

export default React.memo(TodoListItem);

react-visualized 사용 후

import React from 'react';
import { IoIosRemoveCircleOutline } from 'react-icons/io';
import { MdCheckBoxOutlineBlank, MdOutlineCheckBox } from 'react-icons/md';
import './../css/TodoListItem.css';

const TodoListItem = ({ todo, onRemove, onToggle, style }) => {
  const { id, text, checked } = todo;
  return (
    <div className="TodoListItem-visualized" style={style}>
      ~ 기존 컴포넌트 ~
    </div>
  );
};

export default React.memo(TodoListItem);

기존에 보여주던 내용을 div로 한번 더 감싸고, props로 받아온 style을 적용한다. div로 감싸는 과정에서 깨진 스타일을 수정한다.

 

결과

react-visualized 사용 전

render durations : 12.1ms

 

react-visualized 사용 후

render durations : 2.7ms