如果之前的搜索返回了很多结果,为什么我的JavaScript搜索速度会慢很多?

时间:2017-07-31 01:52:08

标签: javascript performance html-rendering reflow

我在写的网络应用中有一个非常奇怪的效果。当前搜索结果的数量对下一次搜索的速度有很大影响,即使搜索没有使用结果列表。

我不确定我应该在这里发布多少代码来演示应用程序的功能,但整个应用程序都在http://connective-lex.info上线。 (要查看效果,请选择所有词典,然后更改搜索选项,例如,选中一个或不检查。)

这是查询功能。标记为!!!的第一行清除了之前的结果列表,从而实现了非常快速的搜索。如果此行被注释掉,搜索开始的速度会快一些,但如果前面的结果列表中有很多项目,那么搜索速度会非常慢。

结果列表为this.results,并且未在搜索代码中使用。它也没有在ResultsFilter类中使用,它进行了实际的过滤,为了简洁我省略了它,但如果你需要更多的话,我会很乐意发布更多的代码。

  // File: c24-components.js
  // Class: ResultsComponent
  ExecuteQuery() {
    setTimeout(() => this.SetResults([]), 0); // !!!
    let tempResults = [];
    let lexIds = Object.keys(gSelectorComponent.lex);
    let totalSize = lexIds.map(lexId => gSelectorComponent.lex[lexId].entry.length).
                                          reduce((acc, val) => acc + val, 0);
    let resultsFilter = new ResultsFilter(totalSize);
    let processAtOnce = 20;

    this.activeSearches.forEach(timeoutId => clearTimeout(timeoutId));
    this.activeSearches.length = 0;

    /* Subfunction which emulates asynchronous processing in the (single-threaded) 
       JS environment by processing a slice of entries and then enqueuing the next 
       slice to be processed so that the browser has time to process user events 
       and render the GUI between slices. */
    let processingFunction = (lexIdIndex, entryIndex) => {
      if (lexIdIndex >= lexIds.length) {
        this.activeSearches.push(setTimeout(() => this.SetResults(tempResults), 0));
        return;
      }

      let entries = undefined;
      try {
        entries = gSelectorComponent.lex[lexIds[lexIdIndex]].entry;
      } catch (e) {
        // This happens when a lexicon is deselected while a search is running.
        // Abort search.
        return;
      }

      for (let i = 0; i < processAtOnce; ++i, ++entryIndex) {
        if (entryIndex >= entries.length) {
          this.activeSearches.push(setTimeout(processingFunction, 0, ++lexIdIndex, 0));
          return;
        }

        if (resultsFilter.TestEntry(entries[entryIndex])) {
          tempResults.push(entries[entryIndex]);
        }
      }

      this.activeSearches.push(setTimeout(processingFunction, 0, lexIdIndex, 
        entryIndex));
    };

    this.activeSearches.push(setTimeout(processingFunction, 0, 0, 0));
  }

更新:如果我正确理解了Chrome的效果工具,则这是因更新进度条而导致的重排问题。在每次更新时,JS都花费大量时间在&#34;更新层树&#34;渲染操作,这似乎是唯一的区别,如果显示更多的先前结果,则需要更长的时间。我想知道如何摆脱这种效果,但仍然显示进展。

0 个答案:

没有答案