Răsfoiți Sursa

Performance improvements/fixes (#592)

Jonathan Swoboda 4 zile în urmă
părinte
comite
bcaf930531
4 a modificat fișierele cu 43 adăugiri și 19 ștergeri
  1. 1 1
      src/connect.ts
  2. 2 2
      src/install-dialog.ts
  3. 39 15
      src/util/console-color.ts
  4. 1 1
      src/util/line-break-transformer.ts

+ 1 - 1
src/connect.ts

@@ -21,7 +21,7 @@ export const connect = async (button: InstallButton) => {
   }
 
   try {
-    await port.open({ baudRate: 115200 });
+    await port.open({ baudRate: 115200, bufferSize: 8192 });
   } catch (err: any) {
     alert(err.message);
     return;

+ 2 - 2
src/install-dialog.ts

@@ -923,13 +923,13 @@ export class EwtInstallDialog extends LitElement {
         if (state.state === FlashStateType.FINISHED) {
           sleep(100)
             // Flashing closes the port
-            .then(() => this.port.open({ baudRate: 115200 }))
+            .then(() => this.port.open({ baudRate: 115200, bufferSize: 8192 }))
             .then(() => this._initialize(true))
             .then(() => this.requestUpdate());
         } else if (state.state === FlashStateType.ERROR) {
           sleep(100)
             // Flashing closes the port
-            .then(() => this.port.open({ baudRate: 115200 }));
+            .then(() => this.port.open({ baudRate: 115200, bufferSize: 8192 }));
         }
       },
       this.port,

+ 39 - 15
src/util/console-color.ts

@@ -6,6 +6,7 @@ interface ConsoleState {
   foregroundColor: string | null;
   backgroundColor: string | null;
   carriageReturn: boolean;
+  lines: string[];
   secret: boolean;
 }
 
@@ -18,6 +19,7 @@ export class ColoredConsole {
     foregroundColor: null,
     backgroundColor: null,
     carriageReturn: false,
+    lines: [],
     secret: false,
   };
 
@@ -27,26 +29,13 @@ export class ColoredConsole {
     return this.targetElement.innerText;
   }
 
-  addLine(line: string) {
+  processLine(line: string): Element {
     // @ts-expect-error
     const re = /(?:\033|\\033)(?:\[(.*?)[@-~]|\].*?(?:\007|\033\\))/g;
     let i = 0;
 
-    if (this.state.carriageReturn) {
-      if (line !== "\n") {
-        // don't remove if \r\n
-        this.targetElement.removeChild(this.targetElement.lastChild!);
-      }
-      this.state.carriageReturn = false;
-    }
-
-    if (line.includes("\r")) {
-      this.state.carriageReturn = true;
-    }
-
     const lineSpan = document.createElement("span");
     lineSpan.classList.add("line");
-    this.targetElement.appendChild(lineSpan);
 
     const addSpan = (content: string) => {
       if (content === "") return;
@@ -179,17 +168,52 @@ export class ColoredConsole {
         }
       }
     }
+    addSpan(line.substring(i));
+    return lineSpan;
+  }
+
+  processLines() {
     const atBottom =
       this.targetElement.scrollTop >
       this.targetElement.scrollHeight - this.targetElement.offsetHeight - 50;
+    const prevCarriageReturn = this.state.carriageReturn;
+    const fragment = document.createDocumentFragment();
 
-    addSpan(line.substring(i));
+    if (this.state.lines.length == 0) {
+      return;
+    }
+
+    for (const line of this.state.lines) {
+      if (this.state.carriageReturn && line !== "\n") {
+        if (fragment.childElementCount) {
+          fragment.removeChild(fragment.lastChild!);
+        }
+      }
+      fragment.appendChild(this.processLine(line));
+      this.state.carriageReturn = line.includes("\r");
+    }
+
+    if (prevCarriageReturn && this.state.lines[0] !== "\n") {
+      this.targetElement.replaceChild(fragment, this.targetElement.lastChild!);
+    } else {
+      this.targetElement.appendChild(fragment);
+    }
+
+    this.state.lines = [];
 
     // Keep scroll at bottom
     if (atBottom) {
       this.targetElement.scrollTop = this.targetElement.scrollHeight;
     }
   }
+
+  addLine(line: string) {
+    // Processing of lines is deferred for performance reasons
+    if (this.state.lines.length == 0) {
+      setTimeout(() => this.processLines(), 0);
+    }
+    this.state.lines.push(line);
+  }
 }
 
 export const coloredConsoleStyles = `

+ 1 - 1
src/util/line-break-transformer.ts

@@ -8,7 +8,7 @@ export class LineBreakTransformer implements Transformer<string, string> {
     // Append new chunks to existing chunks.
     this.chunks += chunk;
     // For each line breaks in chunks, send the parsed lines out.
-    const lines = this.chunks.split("\r\n");
+    const lines = this.chunks.split(/\r?\n/);
     this.chunks = lines.pop()!;
     lines.forEach((line) => controller.enqueue(line + "\r\n"));
   }