Skip to content

Commit 6db1455

Browse files
committed
Enhance performance diagnostics and pointer drag handling during capture
- Add long-animation-frame and event timing PerformanceObserver integrations for deeper frame/event bottleneck visibility - Profile native graph-canvas DOM event handlers (pointer/mouse/wheel) alongside LiteGraph methods - Introduce RAF-scheduled canvas pointer drag helpers (schedule/flush/cancel/clear) used during capture - Initialize supporting pending-drag state fields on ResolutionMasterCanvas These changes improve observability of rendering and event-loop issues while keeping captured pointer drag operations smooth and non-blocking.
1 parent 102f064 commit 6db1455

3 files changed

Lines changed: 365 additions & 7 deletions

File tree

js/interaction/resolution_master_interaction_methods.js

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,62 @@ export const interactionMethods = {
222222
|| null;
223223
},
224224

225+
scheduleCanvasPointerDrag(eMove, activeCanvas) {
226+
this._pendingCanvasPointerDragEvent = eMove;
227+
this._pendingCanvasPointerDragCanvas = activeCanvas;
228+
if (this._pendingCanvasPointerDragFrame !== null) return;
229+
230+
const runPendingDrag = () => {
231+
this._pendingCanvasPointerDragFrame = null;
232+
this._pendingCanvasPointerDragCancel = null;
233+
const pendingEvent = this._pendingCanvasPointerDragEvent;
234+
const pendingCanvas = this._pendingCanvasPointerDragCanvas;
235+
this._pendingCanvasPointerDragEvent = null;
236+
this._pendingCanvasPointerDragCanvas = null;
237+
238+
if (!pendingEvent || !this.node?.capture) return;
239+
this.handleMouseMove(pendingEvent, null, pendingCanvas);
240+
};
241+
242+
if (globalThis.requestAnimationFrame) {
243+
this._pendingCanvasPointerDragFrame = globalThis.requestAnimationFrame(runPendingDrag);
244+
this._pendingCanvasPointerDragCancel = globalThis.cancelAnimationFrame?.bind(globalThis) || null;
245+
return;
246+
}
247+
248+
if (globalThis.setTimeout) {
249+
this._pendingCanvasPointerDragFrame = globalThis.setTimeout(runPendingDrag, 16);
250+
this._pendingCanvasPointerDragCancel = globalThis.clearTimeout?.bind(globalThis) || null;
251+
return;
252+
}
253+
254+
runPendingDrag();
255+
},
256+
257+
cancelPendingCanvasPointerDragFrame() {
258+
if (this._pendingCanvasPointerDragFrame === null) return;
259+
this._pendingCanvasPointerDragCancel?.(this._pendingCanvasPointerDragFrame);
260+
this._pendingCanvasPointerDragFrame = null;
261+
this._pendingCanvasPointerDragCancel = null;
262+
},
263+
264+
flushCanvasPointerDrag() {
265+
const pendingEvent = this._pendingCanvasPointerDragEvent;
266+
const pendingCanvas = this._pendingCanvasPointerDragCanvas;
267+
this.cancelPendingCanvasPointerDragFrame();
268+
this._pendingCanvasPointerDragEvent = null;
269+
this._pendingCanvasPointerDragCanvas = null;
270+
271+
if (!pendingEvent || !this.node?.capture) return;
272+
this.handleMouseMove(pendingEvent, null, pendingCanvas);
273+
},
274+
275+
clearCanvasPointerDrag() {
276+
this.cancelPendingCanvasPointerDragFrame();
277+
this._pendingCanvasPointerDragEvent = null;
278+
this._pendingCanvasPointerDragCanvas = null;
279+
},
280+
225281
captureNodePointer(canvas) {
226282
const pointer = this.getCanvasPointer(canvas);
227283
if (pointer && ("onDrag" in pointer || "finally" in pointer)) {
@@ -234,9 +290,10 @@ export const interactionMethods = {
234290
|| null;
235291

236292
pointer.onDrag = (eMove) => {
237-
this.handleMouseMove(eMove, null, activeCanvas);
293+
this.scheduleCanvasPointerDrag(eMove, activeCanvas);
238294
};
239295
pointer.finally = () => {
296+
this.flushCanvasPointerDrag();
240297
if (this.node?.capture) {
241298
this.handleMouseUp(pointer.eUp || pointer.eMove || pointer.eDown);
242299
}
@@ -268,6 +325,7 @@ export const interactionMethods = {
268325
releaseNodePointer(canvas) {
269326
const pointer = this.getCanvasPointer(canvas);
270327
if (pointer && ("onDrag" in pointer || "finally" in pointer)) {
328+
this.clearCanvasPointerDrag();
271329
this._usingCanvasPointerCallbacks = false;
272330
this._capturedPointerCanvas = null;
273331
return;
@@ -287,6 +345,7 @@ export const interactionMethods = {
287345
});
288346
}
289347
this.node.captureInput?.(false);
348+
this.clearCanvasPointerDrag();
290349
this._usingCanvasPointerCallbacks = false;
291350
this._capturedPointerCanvas = null;
292351
},

js/resolution_master.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ class ResolutionMasterCanvas {
6767
this.awaitingLivePreviewReason = null;
6868
this.manuallySetByAutoFit = false;
6969
this.canvasDragAspectLock = null;
70+
this._pendingCanvasPointerDragEvent = null;
71+
this._pendingCanvasPointerDragCanvas = null;
72+
this._pendingCanvasPointerDragFrame = null;
73+
this._pendingCanvasPointerDragCancel = null;
7074
this.canvasDotsCache = null;
7175
this.controls = {};
7276
this.resolutions = [...RESOLUTION_OPTIONS];

0 commit comments

Comments
 (0)