我们已经在大约1200个条目的数组上实现了搜索功能,带有6个过滤器和一个搜索关键字。当用户选择任何过滤器或键入关键字时,将执行“自动”搜索以过滤显示的结果。问题在于,过滤后的数组的重新渲染速度比预期的慢,导致在渲染内容时应用程序冻结了不到一秒钟的时间。我的问题是如何优化以下代码,以带来更好的用户体验,即在键入搜索关键字或选择过滤器时,结果应快速显示或以不会干扰用户的方式显示?
我们拥有的结构是一个父组件,其中包含2个子组件:一个是Search
包含下拉列表形式的过滤器的条形,另一个是每行SearchResultsList
呈现4个Bootstrap-Vueb-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
组件仅渲染输入的道具: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
)
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句