Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance issues vs react-sortable-hoc #600

Closed
jarcoal opened this issue Jan 24, 2022 · 2 comments
Closed

Performance issues vs react-sortable-hoc #600

jarcoal opened this issue Jan 24, 2022 · 2 comments

Comments

@jarcoal
Copy link

jarcoal commented Jan 24, 2022

We recently refactored our usage of react-sortable-hoc to dnd-kit, and I noticed that there is a pretty significant performance hit that came with the switch.

With the element inspector open the sortable functionality grounds to a halt when dragging items around, and while it's smoother with the inspector closed, it still eats up a ton of CPU (~130% on my machine, vs ~20% with react-sortable-hoc).

Even just comparing these two grid examples I see significantly better performance from the react-sortable-hoc example:

My tests aren't very scientific, I'm just keeping the activity monitor open while dragging things around, but the problem is definitely real in our app -- the dragging functionality is quite laggy.

Let me know if there is something I can provide that will shed more light on the issue. Thanks!

@clauderic
Copy link
Owner

clauderic commented Jan 25, 2022

There are many difference between react-sortable-hoc and @dnd-kit. @dnd-kit handles significantly more complexity than react-sortable-hoc does; as such, it's definitely doing a lot more work behind the scenes, so it's not exactly a fair comparison.

Having said that, the main difference you're likely noticing is that unlike react-sortable-hoc, @dnd-kit actually re-renders items that call useSortable while dragging. In react-sortable-hoc, transforms and transitions were applied directly on the DOM elements themselves, outside of React's lifecycle. This is definitely more performant, but means you can't respond to these changes in React to declaratively re-render your application.

It's hard to help diagnose the issues you're facing without seeing the use-case and code you're using, but one thing I can recommend is splitting your components that use useSortable between a wrapper that receives the transform, listeners and transitions, and a memoized sub-component that doesn't need to re-render when the transform and transition changes. Something like this:

import {memo} from 'react';
import {useSortable} from '@dnd-kit/sortable';
import {CSS} from '@dnd-kit/utilities';

function SortableItem(props) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
  } = useSortable({id: props.id});
  
  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  };
  
  return (
    <li ref={setNodeRef} style={style} {...attributes} {...listeners}>
      <MemoizedItem {...props} />
    </li>
  );
}

const MemoizedItem = memo(Item);

If you're rendering a significant number of items, you may want to consider virtualizing the list.

@jarcoal
Copy link
Author

jarcoal commented Jan 25, 2022

Thank you -- memoizing the item worked like a charm, the sorting is silky smooth again.

@jarcoal jarcoal closed this as completed Jan 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants