14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

react-beautiful-dnd パフォーマンス最適化

Last updated at Posted at 2018-10-22

まえがき

React で Drag and Drop をしたかったので、atlassian/react-beautiful-dnd を使った。
Trello みたいにヌルヌル dnd できるのですごい。Github Star の伸びも React ライブラリにしてはすごい。
サンプル動画

動作重い問題

README.md でも performance の話がちょいちょいあるが、無駄な re-render を防がないと重くなってしまう。
僕が今回実装してみても、はじめ動きがカクカクになってとても使いにくかったので、README.md 参考にパフォーマンス最適化をした。

最適化

Recommended Droppable performance optimisation を参考にした。
ドキュメントのとおり実装してみてもカクカクし続けたけど、下の DraggableListItem.shouldComponentUpdateを書いてからカクカクしなくなった!

未選択リストと選択中リスト間でitemを移動させるやつ.jsx
class DraggableListItem extends React.Component {
  shouldComponentUpdate(nextProps) {
    return this.props.index !== nextProps.index; // これ!
  }

  render() {
    return (
      <Draggable draggableId={this.props.item.id} index={this.props.index}>
        {(provided, snapshot) =>
          <li
            ref={provided.innerRef}
            {...provided.draggableProps}
            {...provided.dragHandleProps}
          >
            {item.name}
          </li>}
      </Draggable>
    );
  }
}

class InnerList extends React.Component {
  shouldComponentUpdate(nextProps) {
    return this.props.items !== nextProps.items;
  }

  render() {
    const { items } = this.props;
    return items.map((item, index) => {
      return (
        <DraggableListItem
          key={item.id}
          item={item}
          index={index}
        />
      );
    });
  }
}

// DragDropContext の中身
class ItemPicker extends React.Component {
    render() {
        return (
          <>
            <div>
              <h2>未選択</h2>
              <Droppable droppableId="unselected">
                {(provided, snapshot) =>
                  <ul ref={provided.innerRef}>
                    <InnerList items={this.props.unselectedItemList} />
                    {provided.placeholder}
                  </ul>}
              </Droppable>
            </div>
    
            <div>
              <h2>選択中</h2>
              <Droppable droppableId="selected">
                {(provided, snapshot) =>
                  <ul ref={provided.innerRef}>
                    <InnerList items={this.props.selectedItemList} />
                    {provided.placeholder}
                  </ul>}
              </Droppable>
            </div>
          </>
        );
    }
}
14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?