Fix shape drag perf (#1932)
This prevents geometry from being recalculated when dragging shapes around. It uses an equality check on the shape props to opt out of recalculations. This still allows bounds to be calculated based on other reactive values, so if folks really want to use x,y values or opacity or whatever, they can call editor.getShape(id) when making their calculation. ### Change Type - [x] `patch` — Bug fix - [ ] `minor` — New feature - [ ] `major` — Breaking change - [ ] `dependencies` — Changes to package dependencies[^1] - [ ] `documentation` — Changes to the documentation only[^2] - [ ] `tests` — Changes to any test code only[^2] - [ ] `internal` — Any other changes that don't affect the published package[^2] - [ ] I don't know [^1]: publishes a `patch` release, for devDependencies use `internal` [^2]: will not publish a new version ### Release Notes - Fixes a perf regression for dragging shapes around
This commit is contained in:
parent
db58d9c54f
commit
386a2396d1
3 changed files with 16 additions and 8 deletions
|
@ -3724,9 +3724,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
|
||||
@computed
|
||||
private get _shapeGeometryCache(): ComputedCache<Geometry2d, TLShape> {
|
||||
return this.store.createComputedCache('bounds', (shape) => {
|
||||
return this.getShapeUtil(shape).getGeometry(shape)
|
||||
})
|
||||
return this.store.createComputedCache(
|
||||
'bounds',
|
||||
(shape) => this.getShapeUtil(shape).getGeometry(shape),
|
||||
(a, b) => a.props === b.props
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -230,7 +230,7 @@ export class Store<R extends UnknownRecord = UnknownRecord, Props = unknown> {
|
|||
// (undocumented)
|
||||
applyDiff(diff: RecordsDiff<R>, runCallbacks?: boolean): void;
|
||||
clear: () => void;
|
||||
createComputedCache: <T, V extends R = R>(name: string, derive: (record: V) => T | undefined) => ComputedCache<T, V>;
|
||||
createComputedCache: <T, V extends R = R>(name: string, derive: (record: V) => T | undefined, isEqual?: ((a: V, b: V) => boolean) | undefined) => ComputedCache<T, V>;
|
||||
createSelectedComputedCache: <T, J, V extends R = R>(name: string, selector: (record: V) => T | undefined, derive: (input: T) => J | undefined) => ComputedCache<J, V>;
|
||||
// @internal (undocumented)
|
||||
ensureStoreIsUsable(): void;
|
||||
|
|
|
@ -766,7 +766,8 @@ export class Store<R extends UnknownRecord = UnknownRecord, Props = unknown> {
|
|||
*/
|
||||
createComputedCache = <T, V extends R = R>(
|
||||
name: string,
|
||||
derive: (record: V) => T | undefined
|
||||
derive: (record: V) => T | undefined,
|
||||
isEqual?: (a: V, b: V) => boolean
|
||||
): ComputedCache<T, V> => {
|
||||
const cache = new Cache<Atom<any>, Computed<T | undefined>>()
|
||||
return {
|
||||
|
@ -775,9 +776,14 @@ export class Store<R extends UnknownRecord = UnknownRecord, Props = unknown> {
|
|||
if (!atom) {
|
||||
return undefined
|
||||
}
|
||||
return cache.get(atom, () =>
|
||||
computed<T | undefined>(name + ':' + id, () => derive(atom.value as V))
|
||||
).value
|
||||
return cache.get(atom, () => {
|
||||
const recordSignal = isEqual
|
||||
? computed(atom.name + ':equals', () => atom.value, { isEqual })
|
||||
: atom
|
||||
return computed<T | undefined>(name + ':' + id, () => {
|
||||
return derive(recordSignal.value as V)
|
||||
})
|
||||
}).value
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue