-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ui): improve IAIDndImage performance
`dnd-kit` has a problem where, when drag events start and stop, every item that uses the library rerenders. This occurs due to its use of context. The dnd library needs to listen for pointer events to handle dragging. Because our images are both clickable (selectable) and draggable, every time you click an image, the dnd necessarily sees this event, its context updates and all other dnd-enabled components rerender. With a lot of images in gallery and/or batch manager, this leads to some jank. There is an open PR to address this: clauderic/dnd-kit#1096 But unfortunately, the maintainer hasn't accepted any changes for a few months, and its not clear if this will be merged any time soon :/ This change simply extracts the draggable and droppable logic out of IAIDndImage into their own minimal components. Now only these need to rerender when the dnd context is changed. The rerenders are far less impactful now. Hopefully the linked PR is accepted and we get even more efficient dnd functionality in the future. Also changed dnd activation constraint to distance (currently 10px) instead of delay and updated the stacking context of IAIDndImage subcomponents so that the reset and upload buttons still work.
- Loading branch information
1 parent
560a591
commit 8501ca0
Showing
7 changed files
with
148 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
invokeai/frontend/web/src/common/components/IAIDraggable.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Box } from '@chakra-ui/react'; | ||
import { | ||
TypesafeDraggableData, | ||
useDraggable, | ||
} from 'app/components/ImageDnd/typesafeDnd'; | ||
import { MouseEvent, memo, useRef } from 'react'; | ||
import { v4 as uuidv4 } from 'uuid'; | ||
|
||
type IAIDraggableProps = { | ||
disabled?: boolean; | ||
data?: TypesafeDraggableData; | ||
onClick?: (event: MouseEvent<HTMLDivElement>) => void; | ||
}; | ||
|
||
const IAIDraggable = (props: IAIDraggableProps) => { | ||
const { data, disabled, onClick } = props; | ||
const dndId = useRef(uuidv4()); | ||
|
||
const { attributes, listeners, setNodeRef } = useDraggable({ | ||
id: dndId.current, | ||
disabled, | ||
data, | ||
}); | ||
|
||
return ( | ||
<Box | ||
onClick={onClick} | ||
ref={setNodeRef} | ||
position="absolute" | ||
w="full" | ||
h="full" | ||
{...attributes} | ||
{...listeners} | ||
/> | ||
); | ||
}; | ||
|
||
export default memo(IAIDraggable); |
45 changes: 45 additions & 0 deletions
45
invokeai/frontend/web/src/common/components/IAIDroppable.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { Box } from '@chakra-ui/react'; | ||
import { | ||
TypesafeDroppableData, | ||
isValidDrop, | ||
useDroppable, | ||
} from 'app/components/ImageDnd/typesafeDnd'; | ||
import { AnimatePresence } from 'framer-motion'; | ||
import { memo, useRef } from 'react'; | ||
import { v4 as uuidv4 } from 'uuid'; | ||
import IAIDropOverlay from './IAIDropOverlay'; | ||
|
||
type IAIDroppableProps = { | ||
dropLabel?: string; | ||
disabled?: boolean; | ||
data?: TypesafeDroppableData; | ||
}; | ||
|
||
const IAIDroppable = (props: IAIDroppableProps) => { | ||
const { dropLabel, data, disabled } = props; | ||
const dndId = useRef(uuidv4()); | ||
|
||
const { isOver, setNodeRef, active } = useDroppable({ | ||
id: dndId.current, | ||
disabled, | ||
data, | ||
}); | ||
|
||
return ( | ||
<Box | ||
ref={setNodeRef} | ||
position="absolute" | ||
w="full" | ||
h="full" | ||
pointerEvents="none" | ||
> | ||
<AnimatePresence> | ||
{isValidDrop(data, active) && ( | ||
<IAIDropOverlay isOver={isOver} label={dropLabel} /> | ||
)} | ||
</AnimatePresence> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default memo(IAIDroppable); |
19 changes: 4 additions & 15 deletions
19
invokeai/frontend/web/src/features/batch/components/BatchImageContainer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.