From 9879fe4d11e47bb2be72a16c643949eb8fa55453 Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Mon, 22 Jan 2024 23:18:30 -0800 Subject: [PATCH] small performance update for history info. separate each item into a full react component to allow for fine grained reactive updates (prevents large tree reconcilations when there are thousands of history items) (#246) --- src/app/common/common.tsx | 2 +- src/app/workspace/cmdinput/historyinfo.tsx | 108 ++++++++++++--------- 2 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/app/common/common.tsx b/src/app/common/common.tsx index be5236c21..b9b590d1c 100644 --- a/src/app/common/common.tsx +++ b/src/app/common/common.tsx @@ -869,7 +869,7 @@ class Markdown extends React.Component< return {props.children}; } else { let clickHandler = (e: React.MouseEvent) => { - let blockText = e.target.innerText; + let blockText = (e.target as HTMLElement).innerText; if (blockText) { blockText = blockText.replace(/\n$/, ""); // remove trailing newline navigator.clipboard.writeText(blockText); diff --git a/src/app/workspace/cmdinput/historyinfo.tsx b/src/app/workspace/cmdinput/historyinfo.tsx index ee82d4a61..59874ee01 100644 --- a/src/app/workspace/cmdinput/historyinfo.tsx +++ b/src/app/workspace/cmdinput/historyinfo.tsx @@ -29,43 +29,17 @@ function truncateWithTDots(str: string, maxLen: number): string { } @mobxReact.observer -class HistoryInfo extends React.Component<{}, {}> { - lastClickHNum: string = null; - lastClickTs: number = 0; - containingText: mobx.IObservableValue = mobx.observable.box(""); - - componentDidMount() { - let inputModel = GlobalModel.inputModel; - let hitem = inputModel.getHistorySelectedItem(); - if (hitem == null) { - hitem = inputModel.getFirstHistoryItem(); - } - if (hitem != null) { - inputModel.scrollHistoryItemIntoView(hitem.historynum); - } - } - - @boundMethod - handleItemClick(hitem: HistoryItem) { - let inputModel = GlobalModel.inputModel; - let selItem = inputModel.getHistorySelectedItem(); - if (this.lastClickHNum == hitem.historynum && selItem != null && selItem.historynum == hitem.historynum) { - inputModel.grabSelectedHistoryItem(); - return; - } - inputModel.giveFocus(); - inputModel.setHistorySelectionNum(hitem.historynum); - let now = Date.now(); - this.lastClickHNum = hitem.historynum; - this.lastClickTs = now; - setTimeout(() => { - if (this.lastClickTs == now) { - this.lastClickHNum = null; - this.lastClickTs = 0; - } - }, 3000); - } - +class HItem extends React.Component< + { + hitem: HistoryItem; + isSelected: boolean; + opts: HistoryQueryOpts; + snames: Record; + scrNames: Record; + onClick: (hitem: HistoryItem) => void; + }, + {} +> { renderRemote(hitem: HistoryItem): any { if (hitem.remote == null || isBlank(hitem.remote.remoteid)) { return sprintf("%-15s ", ""); @@ -142,13 +116,8 @@ class HistoryInfo extends React.Component<{}, {}> { return "-"; } - renderHItem( - hitem: HistoryItem, - opts: HistoryQueryOpts, - isSelected: boolean, - snames: Record, - scrNames: Record - ): any { + render() { + let { hitem, isSelected, opts, snames, scrNames } = this.props; let lines = hitem.cmdstr.split("\n"); let line: string = ""; let idx = 0; @@ -163,7 +132,7 @@ class HistoryInfo extends React.Component<{}, {}> { { "history-haderror": hitem.haderror }, "hnum-" + hitem.historynum )} - onClick={() => this.handleItemClick(hitem)} + onClick={() => this.props.onClick(hitem)} >
{infoText} {lines[0]} @@ -176,12 +145,51 @@ class HistoryInfo extends React.Component<{}, {}> {
); } +} + +@mobxReact.observer +class HistoryInfo extends React.Component<{}, {}> { + lastClickHNum: string = null; + lastClickTs: number = 0; + containingText: mobx.IObservableValue = mobx.observable.box(""); + + componentDidMount() { + let inputModel = GlobalModel.inputModel; + let hitem = inputModel.getHistorySelectedItem(); + if (hitem == null) { + hitem = inputModel.getFirstHistoryItem(); + } + if (hitem != null) { + inputModel.scrollHistoryItemIntoView(hitem.historynum); + } + } @boundMethod handleClose() { GlobalModel.inputModel.toggleInfoMsg(); } + @boundMethod + handleItemClick(hitem: HistoryItem) { + let inputModel = GlobalModel.inputModel; + let selItem = inputModel.getHistorySelectedItem(); + if (this.lastClickHNum == hitem.historynum && selItem != null && selItem.historynum == hitem.historynum) { + inputModel.grabSelectedHistoryItem(); + return; + } + inputModel.giveFocus(); + inputModel.setHistorySelectionNum(hitem.historynum); + let now = Date.now(); + this.lastClickHNum = hitem.historynum; + this.lastClickTs = now; + setTimeout(() => { + if (this.lastClickTs == now) { + this.lastClickHNum = null; + this.lastClickTs = 0; + } + }, 3000); + } + render() { let inputModel = GlobalModel.inputModel; let idx: number = 0; @@ -224,7 +232,15 @@ class HistoryInfo extends React.Component<{}, {}> { [no history] 0}> - {this.renderHItem(hitem, opts, hitem == selItem, snames, scrNames)} +