From 87f70b7de5e05bd0ae6148a04ccbe8e7699492ae Mon Sep 17 00:00:00 2001 From: Steve Ruiz Date: Sat, 13 Apr 2024 21:07:10 +0100 Subject: [PATCH] Perf: Use a computed cache for masked shape page bounds (#3460) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds a computed cache for masked shape page bounds, which speeds up visibility checks (a lot!). ### Change Type - [x] `sdk` — Changes the tldraw SDK - [x] `improvement` — Improving existing features --- packages/editor/src/lib/editor/Editor.ts | 33 +++++++++++++----------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/packages/editor/src/lib/editor/Editor.ts b/packages/editor/src/lib/editor/Editor.ts index b0c38aad3..0f28bcbaa 100644 --- a/packages/editor/src/lib/editor/Editor.ts +++ b/packages/editor/src/lib/editor/Editor.ts @@ -4057,22 +4057,25 @@ export class Editor extends EventEmitter { */ getShapeMaskedPageBounds(shape: TLShapeId | TLShape): Box | undefined { if (typeof shape !== 'string') shape = shape.id - const pageBounds = this._getShapePageBoundsCache().get(shape) - if (!pageBounds) return - const pageMask = this._getShapeMaskCache().get(shape) - if (pageMask) { - if (pageMask.length === 0) return undefined + return this._getShapeMaskedPageBoundsCache().get(shape) + } - const { corners } = pageBounds - if (corners.every((p, i) => p && Vec.Equals(p, pageMask[i]))) return pageBounds.clone() - - // todo: find out why intersect polygon polygon for identical polygons produces zero w/h intersections - const intersection = intersectPolygonPolygon(pageMask, corners) - if (!intersection) return - return Box.FromPoints(intersection) - } - - return pageBounds + /** @internal */ + @computed private _getShapeMaskedPageBoundsCache(): ComputedCache { + return this.store.createComputedCache('shapeMaskedPageBoundsCache', (shape) => { + const pageBounds = this._getShapePageBoundsCache().get(shape.id) + if (!pageBounds) return + const pageMask = this._getShapeMaskCache().get(shape.id) + if (pageMask) { + if (pageMask.length === 0) return undefined + const { corners } = pageBounds + if (corners.every((p, i) => p && Vec.Equals(p, pageMask[i]))) return pageBounds.clone() + const intersection = intersectPolygonPolygon(pageMask, corners) + if (!intersection) return + return Box.FromPoints(intersection) + } + return pageBounds + }) } /**