Skip to content

Commit

Permalink
Reduce frequency of collision detection
Browse files Browse the repository at this point in the history
  • Loading branch information
clauderic committed Jul 16, 2024
1 parent 69bfad7 commit a04d3f8
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/collision-observer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@dnd-kit/abstract': patch
---

Reduce the how frequently collisions are re-computed when the position of the drag operation does not change.
57 changes: 38 additions & 19 deletions packages/abstract/src/core/collision/observer.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import {
batch,
computed,
deepEqual,
signal,
untracked,
type ReadonlySignal,
effect,
} from '@dnd-kit/state';
import {batch, signal, untracked, type Signal, effects} from '@dnd-kit/state';
import type {Coordinates} from '@dnd-kit/geometry';

import type {DragDropManager} from '../manager/index.ts';
import type {Draggable, Droppable} from '../entities/index.ts';
Expand All @@ -25,15 +18,43 @@ export class CollisionObserver<
super(manager);

this.computeCollisions = this.computeCollisions.bind(this);
this.#collisions = computed(this.computeCollisions, deepEqual);
this.#collisions = signal(DEFAULT_VALUE);

this.destroy = effect(() => {
const {dragOperation} = this.manager;
const isEqual = (a: Collision[], b: Collision[]) =>
a.map(({id}) => id).join('') === b.map(({id}) => id).join('');

if (dragOperation.status.initialized) {
this.forceUpdate();
let previousCoordinates: Coordinates = {x: 0, y: 0};

this.destroy = effects(
() => {
const collisions = this.computeCollisions();
const previousCollisions = this.#collisions.peek();

if (isEqual(collisions, previousCollisions)) {
return;
}

const coordinates = untracked(
() => this.manager.dragOperation.position.current
);
const {x, y} = previousCoordinates;

previousCoordinates = coordinates;

if (coordinates.x == x && coordinates.y == y) {
return;
}

this.#collisions.value = collisions;
},
() => {
const {dragOperation} = this.manager;

if (dragOperation.status.initialized) {
this.forceUpdate();
}
}
});
);
}

forceUpdateCount = signal(0);
Expand All @@ -53,7 +74,7 @@ export class CollisionObserver<
}
}

this.forceUpdateCount.value++;
this.#collisions.value = this.computeCollisions();
});
});
}
Expand All @@ -71,8 +92,6 @@ export class CollisionObserver<

const collisions: Collision[] = [];

this.forceUpdateCount.value;

for (const entry of entries ?? registry.droppables) {
if (entry.disabled) {
continue;
Expand Down Expand Up @@ -113,5 +132,5 @@ export class CollisionObserver<
return this.#collisions.value;
}

#collisions: ReadonlySignal<Collisions>;
#collisions: Signal<Collisions>;
}

0 comments on commit a04d3f8

Please sign in to comment.