我正在使用 dndkit 库,尝试通过拖放制作一个简单的可排序列表,从长远来看,我有点担心该应用程序的潜在性能不佳。
在拖动(开始拖动、移过其他项目并放下)时,我一直无法停止或至少最大限度地减少可排序项目的重新渲染。看起来每当您启动拖动事件并移动项目时,项目组件都会重新渲染,因此即使是简单的拖动动画也会导致列表中的所有项目进行数百次重新渲染。我不确定动画是否是导致重新渲染的原因,但我真的很想保留它,同时优化渲染。
这是我的代码片段,说明了问题
import { useState } from "react";
import { DndContext, closestCenter } from "@dnd-kit/core";
import {
arrayMove,
SortableContext,
verticalListSortingStrategy,
useSortable,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
export function App() {
const [items, setItems] = useState(["Item1", "Item2", "Item3"]);
const handleDragEnd = (event) => {
const { active, over } = event;
if (active.id !== over.id) {
setItems((items) => {
const activeIndex = items.indexOf(active.id);
const overIndex = items.indexOf(over.id);
return arrayMove(items, activeIndex, overIndex);
});
}
};
return (
<DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
<div className="p-3">
<SortableContext
items={items}
strategy={verticalListSortingStrategy}
>
{items.map((item, index) => (
<SortableItem key={item} id={item} index={index} />
))}
</SortableContext>
</div>
</DndContext>
);
}
const SortableItem = (props) => {
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id: props.id });
const style = {
transform: CSS.Transform.toString(transform),
transition,
};
console.log(`renderedItem: ${props.index}`);
return (
<div
className="border border-red-500 bg-yellow-50"
ref={setNodeRef}
style={style}
{...attributes}
{...listeners}
>
<div className="p-3">{props.id}</div>
</div>
);
};
我尝试过对组件和项目使用 useMemo 和 memo,但这根本没有帮助。 我还发现了关于软件包存储库问题的建议: https://github.com/clauderic/dnd-kit/issues/994
我尝试过对可排序项目使用“包装组件”,但这仅有助于优化项目卡,包装组件每次仍会重新渲染(我不确定这是否有助于提高性能)。
我之前使用过react-beautiful-dnd库,它在持有可拖动项目时有一个漂亮的拖动覆盖动画,并且它以某种方式设法不导致重新渲染,仅在放置时重新渲染项目(更改排序)。不幸的是,它也有限制,最适合仅垂直和水平排序(特别是看板),并且看起来未来不会进行维护。 Dndkit 在排序时提供类似的漂亮动画风格,并为其他用例提供更大的多功能性,但性能问题有点令人担忧。
有人成功优化过它吗?你是怎么做到的?值得这么麻烦吗?
同样的问题,找不到解决办法