perf(canvas): avoid scene recording during live edits

This commit is contained in:
Danila Poyarkov 2026-04-30 18:29:51 +03:00
parent 9bc9b5d5b0
commit 17e2aa6cb5
2 changed files with 28 additions and 4 deletions

View file

@ -77,6 +77,8 @@ export class SkiaRenderer {
scenePicture: SkPicture | null = null
scenePictureVersion = -1
scenePicturePageId: string | null = null
lastObservedSceneVersion = -1
lastSceneVersionChangeAt = 0
nodePictureCache = new Map<string, SkPicture | null>()
readonly labelCache = new LabelCache()
readonly profiler: RenderProfiler

View file

@ -24,6 +24,9 @@ export function renderSceneToCanvas(
export type RenderLayer = 'full' | 'scene' | 'overlays'
const LIVE_SCENE_CHANGE_MS = 120
const now = typeof performance !== 'undefined' ? () => performance.now() : () => Date.now()
export function renderFromEditorState(
r: SkiaRenderer,
state: EditorState,
@ -77,6 +80,28 @@ export function renderFromEditorState(
)
}
function hasVolatileOverlay(overlays: RenderOverlays): boolean {
return (
overlays.dropTargetId != null ||
overlays.rotationPreview != null ||
overlays.editingTextId != null ||
overlays.nodeEditState != null
)
}
function hasLiveSceneChange(r: SkiaRenderer, sceneVersion: number, layer: RenderLayer): boolean {
if (layer === 'overlays' || sceneVersion < 0 || sceneVersion === r.lastObservedSceneVersion) {
return false
}
const timestamp = now()
const live =
r.lastSceneVersionChangeAt > 0 && timestamp - r.lastSceneVersionChangeAt < LIVE_SCENE_CHANGE_MS
r.lastObservedSceneVersion = sceneVersion
r.lastSceneVersionChangeAt = timestamp
return live
}
export function render(
r: SkiaRenderer,
graph: SceneGraph,
@ -105,10 +130,7 @@ export function render(
}
const hasVolatileOverlays =
overlays.dropTargetId != null ||
overlays.rotationPreview != null ||
overlays.editingTextId != null ||
overlays.nodeEditState != null
hasVolatileOverlay(overlays) || hasLiveSceneChange(r, sceneVersion, layer)
const canUsePicture =
!hasVolatileOverlays &&