Browse Source

fix: improve pointer syncing performance (#4883)

Co-authored-by: dwelle <luzar.david@gmail.com>
Milos Vetesnik 3 years ago
parent
commit
6765fc16be
2 changed files with 16 additions and 9 deletions
  1. 1 0
      src/excalidraw-app/app_constants.ts
  2. 15 9
      src/excalidraw-app/collab/CollabWrapper.tsx

+ 1 - 0
src/excalidraw-app/app_constants.ts

@@ -5,6 +5,7 @@ export const FILE_UPLOAD_TIMEOUT = 300;
 export const LOAD_IMAGES_TIMEOUT = 500;
 export const SYNC_FULL_SCENE_INTERVAL_MS = 20000;
 export const SYNC_BROWSER_TABS_TIMEOUT = 50;
+export const CURSOR_SYNC_TIMEOUT = 33; // ~30fps
 
 export const FILE_UPLOAD_MAX_BYTES = 3 * 1024 * 1024; // 3 MiB
 // 1 year (https://stackoverflow.com/a/25201898/927631)

+ 15 - 9
src/excalidraw-app/collab/CollabWrapper.tsx

@@ -16,6 +16,7 @@ import {
   withBatchedUpdates,
 } from "../../utils";
 import {
+  CURSOR_SYNC_TIMEOUT,
   FILE_UPLOAD_MAX_BYTES,
   FIREBASE_STORAGE_PREFIXES,
   INITIAL_SCENE_UPDATE_TIMEOUT,
@@ -602,7 +603,9 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
       window.clearTimeout(this.idleTimeoutId);
       this.idleTimeoutId = null;
     }
+
     this.idleTimeoutId = window.setTimeout(this.reportIdle, IDLE_THRESHOLD);
+
     if (!this.activeIntervalId) {
       this.activeIntervalId = window.setInterval(
         this.reportActive,
@@ -677,15 +680,18 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
     return this.excalidrawAPI.getSceneElementsIncludingDeleted();
   };
 
-  onPointerUpdate = (payload: {
-    pointer: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["pointer"];
-    button: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["button"];
-    pointersMap: Gesture["pointers"];
-  }) => {
-    payload.pointersMap.size < 2 &&
-      this.portal.socket &&
-      this.portal.broadcastMouseLocation(payload);
-  };
+  onPointerUpdate = throttle(
+    (payload: {
+      pointer: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["pointer"];
+      button: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["button"];
+      pointersMap: Gesture["pointers"];
+    }) => {
+      payload.pointersMap.size < 2 &&
+        this.portal.socket &&
+        this.portal.broadcastMouseLocation(payload);
+    },
+    CURSOR_SYNC_TIMEOUT,
+  );
 
   onIdleStateChange = (userState: UserIdleState) => {
     this.setState({ userState });