繁体   English   中英

如何优化/加速 Vue JS 应用程序中的自动搜索?

[英]How to optimize / speed up automatic search in a Vue JS app?

我们在大约 1200 个条目的数组上实现了搜索功能,其中包含 6 个过滤器和一个搜索关键字。 当用户选择任何过滤器或键入关键字时,将执行“自动”搜索过滤显示的结果。 问题是过滤后的数组重新呈现的速度比预期的要慢,导致应用程序在呈现内容时冻结了几分之一秒。 我的问题是如何优化以下代码以获得更好的用户体验,即在键入搜索关键字或选择过滤器时,结果应该快速显示还是以不会打扰用户的方式显示?

我们拥有的结构是一个父组件,它包含 2 个子组件:一个是包含下拉形式过滤器的Search栏,另一个是SearchResultsList ,它每行渲染 4 个 Bootstrap-Vue b-card ,直到列表用完。

在父级中,我们像这样渲染两个子级:

<b-row
  class="pt-sm-4 p-sm-0 p-2 bg-white"
  no-gutters
>
  <b-col
    sm="12"
    class="px-sm-3 mb-4"
  >
    <!-- People Search Bar -->
    <practice-people-search
      :people="filteredPeopleByKeyword"
      @togglePracticePeopleFiltersEvent="onTogglePracticePeopleFiltersEvent"/>

    <!-- Practice People Search Results List -->
    <practice-people-search-results-list
      :people="filteredPeopleByKeyword"
      :show-practice-people-filters="showPracticePeopleFilters"/>
  </b-col>
</b-row>

我们还有一个created钩子和一些computed properties ,它们分别进行后端调用以获取数据并过滤传入的数组。 我们首先使用默认过滤器和/或任何其他选定的过滤器过滤大型 1200 个条目数组,然后在用户键入关键字时过滤新创建的数组,如下所示

computed: {
    ...mapState('practice', [
      'practicePeopleKeyword',
      'practicePeopleCurrentValue',
      'practicePeopleOfficesValue',
      'practicePeopleGroupsValue',
      'practicePeopleOMGsValue',
      'practicePeopleStatusValue',
      'practicePeoplePositionValue']),
    filteredPeopleByFilters () {
      let filteredPeopleByFiltersArray = []
      for (let i = 0; i < this.people.length; i++) {
        let person = this.people[i]

        let currentResult = (this.practicePeopleCurrentValue.length === 0 || this.practicePeopleCurrentValue.filter((v) => {
          let cr = true
          switch (v.Value) {
            case 0:
              cr = (person.practiceCurrent === 1) && (person.officeCurrent === 1) && (person.groupCurrent === 1)
              break
            case 1:
              cr = (person.practiceCurrent === 0) && (person.started === 1)
              break
            case 2:
              cr = (person.practiceCurrent === 1) && (person.officeCurrent === 0)
              break
            case 3:
              cr = (person.practiceCurrent === 1) && (person.groupCurrent === 0)
              break
            case 4:
              cr = (person.started === 0)
              break
          }
          return cr
        }).length !== 0)
        let officeResult = (this.practicePeopleOfficesValue.length === 0 || this.practicePeopleOfficesValue.filter((v) => { return v.Value === person.mo_ref }).length !== 0)
        let groupResult = (this.practicePeopleGroupsValue.length === 0 || this.practicePeopleGroupsValue.filter((v) => { return v.Value === person.gp_ref }).length !== 0)
        let omgResult = (this.practicePeopleOMGsValue.length === 0 || this.practicePeopleOMGsValue.filter((v) => { return v.Value === person.omg_ref }).length !== 0)
        let statusResult = (this.practicePeopleStatusValue.length === 0 || this.practicePeopleStatusValue.filter((v) => {
          return (v.Value === person.mk_ref) || (v.Value === person.md_type)
        }).length !== 0)
        let positionResult = (this.practicePeoplePositionValue.length === 0 || this.practicePeoplePositionValue.filter((v) => {
          return v.Value === person.ms_ref || ((v.Value === -2) && (person.isPE === 1))
        }).length !== 0)

        if (currentResult && officeResult && groupResult && omgResult & statusResult && positionResult) {
          filteredPeopleByFiltersArray.push(person)
        }
      }
      return filteredPeopleByFiltersArray
    },
    filteredPeopleByKeyword () {
      let filteredPeopleByKeywordArray = []
      for (let i = 0; i < this.filteredPeopleByFilters.length; i++) {
        let person = this.filteredPeopleByFilters[i]

        let searchKeywordResult = (this.practicePeopleKeyword === '' || person.psname.indexOf(this.practicePeopleKeyword) > -1)

        if (searchKeywordResult) {
          filteredPeopleByKeywordArray.push(person)
        }
      }
      return filteredPeopleByKeywordArray
    }
  }

practice-people-search组件中的代码计算了属性以了解哪些过滤器已被选择并将它们存储在 Vuex 中,而practice-people-search-results-list组件纯粹呈现传入的 prop :people="filteredPeopleByKeyword"

我希望上述内容是有道理的,如果有人对如何加快搜索速度有想法,以避免或至少减少故障,我将不胜感激? 干杯

过滤 1200 个元素应该不会很明显。 显示的代码或应用程序的其他地方一定存在一些低效率。

确保filteredPeopleByFilters()不会在每次practicePeopleKeyword更改时调用,而是仅在过滤器更改时调用。 您可以使用快速的临时console.log filteredPeopleByKeyword()相同 - 确保每次更新只调用一次。

同样在if (currentResult && officeResult && groupResult && omgResult & statusResult && positionResult)您没有从短路中受益。 将其更改为类似

    let currentResult = ...
    if (!currentResult) continue;
    let officeResult = ...
    if (!officeResult) continue;
    let groupResult = ...
    if (!groupResult) continue;
    ... etc ...

少写代码。 使用内置函数通常可以加快 JS 代码的运行速度。

例如,尝试更换

filteredPeopleByKeyword () {
  let filteredPeopleByKeywordArray = []
  for (let i = 0; i < this.filteredPeopleByFilters.length; i++) {
    let person = this.filteredPeopleByFilters[i]

    let searchKeywordResult = (this.practicePeopleKeyword === '' || person.psname.indexOf(this.practicePeopleKeyword) > -1)

    if (searchKeywordResult) {
      filteredPeopleByKeywordArray.push(person)
    }
  }
  return filteredPeopleByKeywordArray
}

filteredPeopleByKeyword () {
  return this.filteredPeopleByFilters.filter(
    person => person.psname.indexOf(this.practicePeopleKeyword) > -1
  )
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM