Browse Source

fix(trace-view): Do not recreate fuse in trace view (#32056)

Stop recreating a new instance of fuse each time a search is started.
Tony Xiao 3 years ago
parent
commit
53f8a65286
1 changed files with 50 additions and 34 deletions
  1. 50 34
      static/app/views/performance/traceDetails/content.tsx

+ 50 - 34
static/app/views/performance/traceDetails/content.tsx

@@ -35,10 +35,11 @@ import {IconInfo} from 'sentry/icons';
 import {t, tct, tn} from 'sentry/locale';
 import space from 'sentry/styles/space';
 import {Organization} from 'sentry/types';
+import {defined} from 'sentry/utils';
 import DiscoverQuery from 'sentry/utils/discover/discoverQuery';
 import EventView from 'sentry/utils/discover/eventView';
 import {getDuration} from 'sentry/utils/formatters';
-import {createFuzzySearch} from 'sentry/utils/fuzzySearch';
+import {createFuzzySearch, Fuse} from 'sentry/utils/fuzzySearch';
 import getDynamicText from 'sentry/utils/getDynamicText';
 import {TraceFullDetailed, TraceMeta} from 'sentry/utils/performance/quickTrace/types';
 import {filterTrace, reduceTrace} from 'sentry/utils/performance/quickTrace/utils';
@@ -91,9 +92,54 @@ class TraceDetailsContent extends React.Component<Props, State> {
     filteredTransactionIds: undefined,
   };
 
+  componentDidMount() {
+    this.initFuse();
+  }
+
+  componentDidUpdate(prevProps: Props) {
+    if (this.props.traces !== prevProps.traces) {
+      this.initFuse();
+    }
+  }
+
+  fuse: Fuse<IndexedFusedTransaction> | null = null;
   traceViewRef = React.createRef<HTMLDivElement>();
   virtualScrollbarContainerRef = React.createRef<HTMLDivElement>();
 
+  async initFuse() {
+    if (defined(this.props.traces) && this.props.traces.length > 0) {
+      const transformed: IndexedFusedTransaction[] = this.props.traces.flatMap(trace =>
+        reduceTrace<IndexedFusedTransaction[]>(
+          trace,
+          (acc, transaction) => {
+            const indexed: string[] = [
+              transaction['transaction.op'],
+              transaction.transaction,
+              transaction.project_slug,
+            ];
+
+            acc.push({
+              transaction,
+              indexed,
+            });
+
+            return acc;
+          },
+          []
+        )
+      );
+
+      this.fuse = await createFuzzySearch(transformed, {
+        keys: ['indexed'],
+        includeMatches: true,
+        threshold: 0.6,
+        location: 0,
+        distance: 100,
+        maxPatternLength: 32,
+      });
+    }
+  }
+
   renderTraceLoading() {
     return <LoadingIndicator />;
   }
@@ -177,11 +223,11 @@ class TraceDetailsContent extends React.Component<Props, State> {
     this.setState({searchQuery: searchQuery || undefined}, this.filterTransactions);
   };
 
-  filterTransactions = async () => {
+  filterTransactions = () => {
     const {traces} = this.props;
     const {filteredTransactionIds, searchQuery} = this.state;
 
-    if (!searchQuery || traces === null || traces.length <= 0) {
+    if (!searchQuery || traces === null || traces.length <= 0 || !defined(this.fuse)) {
       if (filteredTransactionIds !== undefined) {
         this.setState({
           filteredTransactionIds: undefined,
@@ -190,37 +236,7 @@ class TraceDetailsContent extends React.Component<Props, State> {
       return;
     }
 
-    const transformed = traces.flatMap(trace =>
-      reduceTrace<IndexedFusedTransaction[]>(
-        trace,
-        (acc, transaction) => {
-          const indexed: string[] = [
-            transaction['transaction.op'],
-            transaction.transaction,
-            transaction.project_slug,
-          ];
-
-          acc.push({
-            transaction,
-            indexed,
-          });
-
-          return acc;
-        },
-        []
-      )
-    );
-
-    const fuse = await createFuzzySearch(transformed, {
-      keys: ['indexed'],
-      includeMatches: true,
-      threshold: 0.6,
-      location: 0,
-      distance: 100,
-      maxPatternLength: 32,
-    });
-
-    const fuseMatches = fuse
+    const fuseMatches = this.fuse
       .search<IndexedFusedTransaction>(searchQuery)
       /**
        * Sometimes, there can be matches that don't include any