瀏覽代碼

[PERF DEBUG]

dwelle 3 年之前
父節點
當前提交
41200ea28d
共有 5 個文件被更改,包括 101 次插入40 次删除
  1. 45 39
      src/components/App.tsx
  2. 2 1
      src/excalidraw-app/collab/Collab.tsx
  3. 47 0
      src/excalidraw-app/index.tsx
  4. 3 0
      src/global.d.ts
  5. 4 0
      src/renderer/renderScene.ts

+ 45 - 39
src/components/App.tsx

@@ -476,6 +476,8 @@ class App extends React.Component<AppProps, AppState> {
     );
   }
 
+  private __renderUI = true;
+
   public render() {
     const selectedElement = getSelectedElements(
       this.scene.getNonDeletedElements(),
@@ -505,43 +507,45 @@ class App extends React.Component<AppProps, AppState> {
           value={this.excalidrawContainerValue}
         >
           <DeviceContext.Provider value={this.device}>
-            <LayerUI
-              canvas={this.canvas}
-              appState={this.state}
-              files={this.files}
-              setAppState={this.setAppState}
-              actionManager={this.actionManager}
-              elements={this.scene.getNonDeletedElements()}
-              onCollabButtonClick={onCollabButtonClick}
-              onLockToggle={this.toggleLock}
-              onPenModeToggle={this.togglePenMode}
-              onInsertElements={(elements) =>
-                this.addElementsFromPasteOrLibrary({
-                  elements,
-                  position: "center",
-                  files: null,
-                })
-              }
-              langCode={getLanguage().code}
-              isCollaborating={this.props.isCollaborating}
-              renderTopRightUI={renderTopRightUI}
-              renderCustomFooter={renderFooter}
-              renderCustomStats={renderCustomStats}
-              showExitZenModeBtn={
-                typeof this.props?.zenModeEnabled === "undefined" &&
-                this.state.zenModeEnabled
-              }
-              showThemeBtn={
-                typeof this.props?.theme === "undefined" &&
-                this.props.UIOptions.canvasActions.theme
-              }
-              libraryReturnUrl={this.props.libraryReturnUrl}
-              UIOptions={this.props.UIOptions}
-              focusContainer={this.focusContainer}
-              library={this.library}
-              id={this.id}
-              onImageAction={this.onImageAction}
-            />
+            {this.__renderUI && (
+              <LayerUI
+                canvas={this.canvas}
+                appState={this.state}
+                files={this.files}
+                setAppState={this.setAppState}
+                actionManager={this.actionManager}
+                elements={this.scene.getNonDeletedElements()}
+                onCollabButtonClick={onCollabButtonClick}
+                onLockToggle={this.toggleLock}
+                onPenModeToggle={this.togglePenMode}
+                onInsertElements={(elements) =>
+                  this.addElementsFromPasteOrLibrary({
+                    elements,
+                    position: "center",
+                    files: null,
+                  })
+                }
+                langCode={getLanguage().code}
+                isCollaborating={this.props.isCollaborating}
+                renderTopRightUI={renderTopRightUI}
+                renderCustomFooter={renderFooter}
+                renderCustomStats={renderCustomStats}
+                showExitZenModeBtn={
+                  typeof this.props?.zenModeEnabled === "undefined" &&
+                  this.state.zenModeEnabled
+                }
+                showThemeBtn={
+                  typeof this.props?.theme === "undefined" &&
+                  this.props.UIOptions.canvasActions.theme
+                }
+                libraryReturnUrl={this.props.libraryReturnUrl}
+                UIOptions={this.props.UIOptions}
+                focusContainer={this.focusContainer}
+                library={this.library}
+                id={this.id}
+                onImageAction={this.onImageAction}
+              />
+            )}
             <div className="excalidraw-textEditorContainer" />
             <div className="excalidraw-contextMenuContainer" />
             {selectedElement.length === 1 && this.state.showHyperlinkPopup && (
@@ -820,7 +824,8 @@ class App extends React.Component<AppProps, AppState> {
 
     if (
       process.env.NODE_ENV === ENV.TEST ||
-      process.env.NODE_ENV === ENV.DEVELOPMENT
+      process.env.NODE_ENV === ENV.DEVELOPMENT ||
+      process.env.REACT_APP_VERCEL_ENV === "preview"
     ) {
       const setState = this.setState.bind(this);
       Object.defineProperties(window.h, {
@@ -6203,7 +6208,8 @@ declare global {
 
 if (
   process.env.NODE_ENV === ENV.TEST ||
-  process.env.NODE_ENV === ENV.DEVELOPMENT
+  process.env.NODE_ENV === ENV.DEVELOPMENT ||
+  process.env.REACT_APP_VERCEL_ENV === "preview"
 ) {
   window.h = window.h || ({} as Window["h"]);
 

+ 2 - 1
src/excalidraw-app/collab/Collab.tsx

@@ -169,7 +169,8 @@ class Collab extends PureComponent<Props, CollabState> {
 
     if (
       process.env.NODE_ENV === ENV.TEST ||
-      process.env.NODE_ENV === ENV.DEVELOPMENT
+      process.env.NODE_ENV === ENV.DEVELOPMENT ||
+      process.env.REACT_APP_VERCEL_ENV === "preview"
     ) {
       window.collab = window.collab || ({} as Window["collab"]);
       Object.defineProperties(window, {

+ 47 - 0
src/excalidraw-app/index.tsx

@@ -84,6 +84,53 @@ import { jotaiStore, useAtomWithInitialValue } from "../jotai";
 import { reconcileElements } from "./collab/reconciliation";
 import { parseLibraryTokensFromUrl, useHandleLibrary } from "../data/library";
 
+const TIMES_AGGR: Record<string, { t: number; times: number[] }> = {};
+const TIMES_AVG: Record<string, { times: number[] }> = {};
+
+window.DEBUG_LOG_TIMES = true;
+
+setInterval(() => {
+  if (window.DEBUG_LOG_TIMES) {
+    for (const [name, { t, times }] of Object.entries(TIMES_AGGR)) {
+      if (times.length) {
+        console.info(
+          name,
+          times.reduce((a, b) => a + b),
+          times.sort((a, b) => a - b),
+        );
+        TIMES_AGGR[name] = { t, times: [] };
+      }
+    }
+    for (const [name, { times }] of Object.entries(TIMES_AVG)) {
+      if (times.length) {
+        console.info(
+          name,
+          parseFloat(
+            (times.reduce((a, b) => a + b) / times.length).toPrecision(5),
+          ),
+          times.sort((a, b) => a - b),
+        );
+        TIMES_AVG[name] = { times: [] };
+      }
+    }
+  }
+}, 1000);
+
+window.logTime = (name: string, time?: number) => {
+  const { t, times } = (TIMES_AGGR[name] = TIMES_AGGR[name] || {
+    t: 0,
+    times: [],
+  });
+  if (t) {
+    times.push(time != null ? time : Date.now() - t);
+  }
+  TIMES_AGGR[name].t = Date.now();
+};
+window.logTimeAverage = (name: string, time: number) => {
+  const { times } = (TIMES_AVG[name] = TIMES_AVG[name] || { times: [] });
+  times.push(time);
+};
+
 polyfill();
 window.EXCALIDRAW_THROTTLE_RENDER = true;
 

+ 3 - 0
src/global.d.ts

@@ -16,6 +16,9 @@ interface Window {
   EXCALIDRAW_EXPORT_SOURCE: string;
   EXCALIDRAW_THROTTLE_RENDER: boolean | undefined;
   gtag: Function;
+  logTime: (name: string, time?: number) => void;
+  logTimeAverage: (name: string, time: number) => void;
+  DEBUG_LOG_TIMES: boolean;
 }
 
 // https://github.com/facebook/create-react-app/blob/ddcb7d5/packages/react-scripts/lib/react-app.d.ts

+ 4 - 0
src/renderer/renderScene.ts

@@ -310,6 +310,8 @@ const renderLinearElementPointHighlight = (
   context.restore();
 };
 
+let t = performance.now();
+
 export const _renderScene = ({
   elements,
   appState,
@@ -330,6 +332,8 @@ export const _renderScene = ({
     if (canvas === null) {
       return { atLeastOneVisibleElement: false };
     }
+    window.logTimeAverage("renderScene", performance.now() - t);
+    t = performance.now();
     const {
       renderScrollbars = true,
       renderSelection = true,