Todo List성능 최적화 #07_react-virtualized를 사용한 최적화

예를들어 배열에 데이터가 2500개가 있으면, user가 브라우저 창으로 볼 수 있는 데이터는 10개정도로 제한되어 있다. 그런데 처음부터 2500개를 렌더링하는 것은 비효율적이다. (데이터가 수천개 그 이상일수록 효율은 최악..)
그래서 유저가 스크롤을 내리면 추가적인 데이터들이 보여지도록 해서 렌더링을 최적화 할 수 있다.

$ yarn add react-virtualized

위의 명령어를 입력해서 설치를 해줘야함.


설치를 완료한 다음에는 item한개 크기를 확인해야함.


이렇게 개발자 도구로 가로, 세로 px을 확인해보면 된다.

항목 크기를 알았으니 이제 밑에 코드에 적용하면 된다.


TodoList.js 수정 ㄱㄱ

import React, { useCallback } from 'react';   // useCallback 추가함.
import { List } from 'react-virtualized';    // List 함수를 사용하기 위해 import해줬음.
import TodoListItem from './TodoListItem';
import './TodoList.scss';

const TodoList = ({ todos, onRemove, onToggle }) => {

    const rowRenderer = useCallback(
        ({ index, key, style }) => {   // index, key, style 이렇게 3가지를 객체 타입으로 받아와서 사용함
            const todo = todos[index];
            return (
                <TodoListItem todo={todo} key={key} onRemove={onRemove} onToggle={onToggle} style={style} />   // return 부분에 있던게 이쪽 함수 안으로 오게됨.
            )
        }, [onRemove, onToggle, todos],
    );
    
    return (
        <List 
            className="TodoList"
            width={512}     // 전체 크기 width
            height={513}    // 전체 크기 height
            rowCount={todos.length}  // item 항목 갯수
            rowHeight={57}      // 1개 항목당 높이
            rowRenderer={rowRenderer}    // 항목 렌더링에 쓰는 함수
            list={todos}        // 배열의 이름
            style={{ outline: 'none' }}     // List를 이용하는데 기본으로 적용되어있는 outline을 none으로 설정했음.
        />
    );
};

export default React.memo(TodoList);

rowRenderer라는 함수를 만들어주었는데, 이 함수를 List component에 props로 설정을 해줘야함.
List component에는 전체크기, 갯수, 높이 등 입력해줘야한다.


TodoListItem.js 수정 ㄱ

import React from 'react';
import {
    MdCheckBoxOutlineBlank,
    MdCheckBox,
    MdRemoveCircleOutline
} from 'react-icons/md';
import cn from 'classnames';
import './TodoListItem.scss';

const TodoListItem = ({ todo, onRemove, onToggle, style }) => {   // style 추가해줌
    const { id, text, checked } = todo;

    return (
        <div className="TodoListItem-virtualized" style={style}>   // TodoListItem-virtualized div로 감싸줬음.
            <div className="TodoListItem">
                <div className={cn('checkbox', { checked })} onClick={() => onToggle(id)}>
                    {checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
                    <div className="text">{text}</div>
                </div>
                <div className="remove" onClick={() => onRemove(id)}>
                    <MdRemoveCircleOutline />
                </div>
            </div>
        </div>
    );
};


export default React.memo(TodoListItem);


TodoListItem.scss 수정 ㄱ

.TodoListItem-virtualized {
    & + & {				// 
        border-top: 1px solid #dee2e6;
    }
    &:nth-child(even) {
        background: #f8f9fa;
    }
}

기존에 만들어놓았던 & + &, &:nth-child(even) 의 border, background 적용되어있던것을 지우고

TodoListItem-virtualized 클래스의 스타일에 적용해줬음.

리스트 목록을 스크롤해서 확인해보니 보여지는 부분에 해당하는 데이터만 렌더링되서 보여지고 있다.

좋은 웹페이지 즐겨찾기