Perf: Incremental culled shapes calculation. (#3411)
Reworks our culling logic: - No longer show the gray rectangles for culled shapes. - Don't use `renderingBoundExpanded`, instead we now use `viewportPageBounds`. I've removed `renderingBoundsExpanded`, but we might want to deprecate it? - There's now a incremental computation of non visible shapes, which are shapes outside of `viewportPageBounds` and shapes that outside of their parents' clipping bounds. - There's also a new `getCulledShapes` function in `Editor`, which uses the non visible shapes computation as a part of the culled shape computation. - Also moved some of the `getRenderingShapes` tests to newly created `getCullingShapes` tests. Feels much better on my old, 2017 ipad (first tab is this PR, second is current prod, third is staging). https://github.com/tldraw/tldraw/assets/2523721/327a7313-9273-4350-89a0-617a30fc01a2 ### Change Type <!-- ❗ Please select a 'Scope' label ❗️ --> - [x] `sdk` — Changes the tldraw SDK - [ ] `dotcom` — Changes the tldraw.com web app - [ ] `docs` — Changes to the documentation, examples, or templates. - [ ] `vs code` — Changes to the vscode plugin - [ ] `internal` — Does not affect user-facing stuff <!-- ❗ Please select a 'Type' label ❗️ --> - [ ] `bugfix` — Bug fix - [ ] `feature` — New feature - [x] `improvement` — Improving existing features - [ ] `chore` — Updating dependencies, other boring stuff - [ ] `galaxy brain` — Architectural changes - [ ] `tests` — Changes to any test code - [ ] `tools` — Changes to infrastructure, CI, internal scripts, debugging tools, etc. - [ ] `dunno` — I don't know ### Test Plan 1. Regular culling shapes tests. Pan / zoom around. Use minimap. Change pages. - [x] Unit Tests - [ ] End to end tests --------- Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This commit is contained in:
parent
2bbab1a790
commit
987b1ac0b9
10 changed files with 357 additions and 401 deletions
|
@ -21,7 +21,6 @@ import { toDomPrecision } from '../../primitives/utils'
|
|||
import { debugFlags } from '../../utils/debug-flags'
|
||||
import { setStyleProperty } from '../../utils/dom'
|
||||
import { nearestMultiple } from '../../utils/nearestMultiple'
|
||||
import { CulledShapes } from '../CulledShapes'
|
||||
import { GeometryDebuggingView } from '../GeometryDebuggingView'
|
||||
import { LiveCollaborators } from '../LiveCollaborators'
|
||||
import { Shape } from '../Shape'
|
||||
|
@ -125,9 +124,6 @@ export function DefaultCanvas({ className }: TLCanvasComponentProps) {
|
|||
<Background />
|
||||
</div>
|
||||
)}
|
||||
<div className="tl-culled-shapes">
|
||||
<CulledShapes />
|
||||
</div>
|
||||
<div
|
||||
ref={rCanvas}
|
||||
draggable={false}
|
||||
|
@ -388,6 +384,30 @@ function ShapesWithSVGs() {
|
|||
</>
|
||||
)
|
||||
}
|
||||
function ReflowIfNeeded() {
|
||||
const editor = useEditor()
|
||||
const culledShapesRef = useRef<Set<TLShapeId>>(new Set())
|
||||
useQuickReactor(
|
||||
'reflow for culled shapes',
|
||||
() => {
|
||||
const culledShapes = editor.getCulledShapes()
|
||||
if (
|
||||
culledShapesRef.current.size === culledShapes.size &&
|
||||
[...culledShapes].every((id) => culledShapesRef.current.has(id))
|
||||
)
|
||||
return
|
||||
|
||||
culledShapesRef.current = culledShapes
|
||||
const canvas = document.getElementsByClassName('tl-canvas')
|
||||
if (canvas.length === 0) return
|
||||
// This causes a reflow
|
||||
// https://gist.github.com/paulirish/5d52fb081b3570c81e3a
|
||||
const _height = (canvas[0] as HTMLDivElement).offsetHeight
|
||||
},
|
||||
[editor]
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
function ShapesToDisplay() {
|
||||
const editor = useEditor()
|
||||
|
@ -408,6 +428,7 @@ function ShapesToDisplay() {
|
|||
{renderingShapes.map((result) => (
|
||||
<Shape key={result.id + '_shape'} {...result} dprMultiple={dprMultiple} />
|
||||
))}
|
||||
{editor.environment.isSafari && <ReflowIfNeeded />}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue