From 67889d9364ea4b8466339e5df3ddc45cefcd8bb7 Mon Sep 17 00:00:00 2001 From: doodlewind <7312949+doodlewind@users.noreply.github.com> Date: Mon, 24 Feb 2025 03:49:04 +0000 Subject: [PATCH] fix(editor): turbo renderer stale frame lag on zooming (#10376) Before: https://github.com/user-attachments/assets/593e91a3-042e-4619-93a0-dca21fa942aa After: https://github.com/user-attachments/assets/779d7582-f7b2-4135-a97a-d1f65c7cb467 This is only a bug fix that ensures correct baseline rendering result. There'll be more optimizations specific for zooming TBD. --- .../viewport-renderer/viewport-renderer.ts | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/blocksuite/affine/shared/src/viewport-renderer/viewport-renderer.ts b/blocksuite/affine/shared/src/viewport-renderer/viewport-renderer.ts index 28eba2cdeb..2c2eb6b057 100644 --- a/blocksuite/affine/shared/src/viewport-renderer/viewport-renderer.ts +++ b/blocksuite/affine/shared/src/viewport-renderer/viewport-renderer.ts @@ -66,13 +66,12 @@ export class ViewportTurboRendererExtension extends LifeCycleWatcher { ); }); - const debounceOptions = { leading: false, trailing: true }; const debouncedRefresh = debounce( () => { this.refresh().catch(console.error); }, 1000, // During this period, fallback to DOM - debounceOptions + { leading: false, trailing: true } ); this.disposables.add( this.std.store.slots.blockUpdated.on(() => { @@ -97,11 +96,12 @@ export class ViewportTurboRendererExtension extends LifeCycleWatcher { return this.std.get(GfxControllerIdentifier).viewport; } - async refresh(force = false) { - if (this.state === 'paused' && !force) return; + async refresh() { + if (this.state === 'paused') return; + this.clearCanvas(); if (this.viewport.zoom > zoomThreshold) { - this.clearCanvas(); + return; } else if (this.canUseBitmapCache()) { this.drawCachedBitmap(this.layoutCache!); } else { @@ -115,8 +115,9 @@ export class ViewportTurboRendererExtension extends LifeCycleWatcher { } invalidate() { - this.clearCache(); - this.clearCanvas(); + this.layoutCache = null; + this.clearTile(); + this.clearCanvas(); // Should clear immediately after content updates } private updateLayoutCache() { @@ -124,11 +125,6 @@ export class ViewportTurboRendererExtension extends LifeCycleWatcher { this.layoutCache = layout; } - private clearCache() { - this.layoutCache = null; - this.clearTile(); - } - private clearTile() { if (this.tile) { this.tile.bitmap.close(); @@ -154,17 +150,13 @@ export class ViewportTurboRendererExtension extends LifeCycleWatcher { this.worker.onmessage = (e: MessageEvent) => { if (e.data.type === 'bitmapPainted') { - this.handlePaintedBitmap(e.data.bitmap, layout, resolve); + this.handlePaintedBitmap(e.data.bitmap, resolve); } }; }); } - private handlePaintedBitmap( - bitmap: ImageBitmap, - layout: ViewportLayout, - resolve: () => void - ) { + private handlePaintedBitmap(bitmap: ImageBitmap, resolve: () => void) { if (this.tile) { this.tile.bitmap.close(); } @@ -172,7 +164,6 @@ export class ViewportTurboRendererExtension extends LifeCycleWatcher { bitmap, zoom: this.viewport.zoom, }; - this.drawCachedBitmap(layout); resolve(); }