perf(editor): reduce per frame viewport dom ops (#9431)

Currently when panning / zooming on whiteboard, both position and transform of each block component are updated per frame. The positioning part lead to heavy layout costs, which can be reduced.

Before (~35fps):

![image](https://github.com/user-attachments/assets/3f6d8a76-26a5-4ed6-a64c-b519a453cbc0)

After (~50fps):

![image](https://github.com/user-attachments/assets/43bc4b0a-db01-4526-8400-2ec95c3bdd0b)

Tested environment: TibetTravel templet, Windows 11, i5-1130G7 1.1GHz
This commit is contained in:
doodlewind
2024-12-30 10:50:33 +00:00
parent 8b3d99929f
commit d4053a345e

View File

@@ -22,6 +22,7 @@ function updateTransform(element: GfxBlockComponent) {
function handleGfxConnection(instance: GfxBlockComponent) {
instance.style.position = 'absolute';
instance.style.willChange = 'transform';
instance.disposables.add(
instance.gfx.viewport.viewportUpdated.on(() => {
@@ -87,11 +88,11 @@ export abstract class GfxBlockComponent<
override renderBlock() {
const { x, y, w, h, zIndex } = this.getRenderingRect();
this.style.left = `${x}px`;
this.style.top = `${y}px`;
this.style.width = `${w}px`;
this.style.height = `${h}px`;
this.style.zIndex = zIndex;
if (this.style.left !== `${x}px`) this.style.left = `${x}px`;
if (this.style.top !== `${y}px`) this.style.top = `${y}px`;
if (this.style.width !== `${w}px`) this.style.width = `${w}px`;
if (this.style.height !== `${h}px`) this.style.height = `${h}px`;
if (this.style.zIndex !== zIndex) this.style.zIndex = zIndex;
return this.renderGfxBlock();
}