Pārlūkot izejas kodu

Debounce localstorage save (#328)

I profiled dragging and it looks like it takes ~3ms to save to localStorage a smallish scene and we're doing it twice per mousemove. Let's debounce so we don't pay that cost on every mouse move.

Stole the implementation from #220 which got reverted.
Christopher Chedeau 5 gadi atpakaļ
vecāks
revīzija
3db7d69849
2 mainītis faili ar 17 papildinājumiem un 2 dzēšanām
  1. 6 2
      src/index.tsx
  2. 11 0
      src/utils.ts

+ 6 - 2
src/index.tsx

@@ -28,7 +28,7 @@ import { renderScene } from "./renderer";
 import { AppState } from "./types";
 import { ExcalidrawElement, ExcalidrawTextElement } from "./element/types";
 
-import { getDateTime, isInputLike, measureText } from "./utils";
+import { getDateTime, isInputLike, measureText, debounce } from "./utils";
 import { KEYS, META_KEY, isArrowKey } from "./keys";
 
 import { findShapeByKey, shapesShortcutKeys } from "./shapes";
@@ -1016,13 +1016,17 @@ export class App extends React.Component<{}, AppState> {
     }
   }
 
+  private saveDebounced = debounce(() => {
+    saveToLocalStorage(elements, this.state);
+  }, 300);
+
   componentDidUpdate() {
     renderScene(elements, this.rc!, this.canvas!, {
       scrollX: this.state.scrollX,
       scrollY: this.state.scrollY,
       viewBackgroundColor: this.state.viewBackgroundColor
     });
-    saveToLocalStorage(elements, this.state);
+    this.saveDebounced();
     if (history.isRecording()) {
       history.pushEntry(history.generateCurrentEntry(elements));
       history.clearRedoStack();

+ 11 - 0
src/utils.ts

@@ -51,3 +51,14 @@ export function measureText(text: string, font: string) {
 
   return { width, height, baseline };
 }
+
+export function debounce<T extends any[]>(
+  fn: (...args: T) => void,
+  timeout: number
+) {
+  let handle = 0;
+  return (...args: T) => {
+    clearTimeout(handle);
+    handle = window.setTimeout(() => fn(...args), timeout);
+  };
+}