Мы реализовали функцию поиска по массиву из 1200 записей, с 6 фильтрами и ключевым словом поиска. Когда пользователь выбирает какой-либо из фильтров или вводит ключевое слово, поиск 'automati c' выполняется для фильтрации отображаемых результатов. Проблема заключается в том, что отфильтрованный массив перерисовывается медленнее, чем ожидалось, что приводит к зависанию приложения на долю секунды во время визуализации контента. Мой вопрос заключается в том, как оптимизировать следующий код, чтобы улучшить взаимодействие с пользователем, т. Е. При вводе поискового ключевого слова или выборе фильтров результаты должны отображаться быстро или таким образом, чтобы это не мешало пользователю?
Структура, которой мы располагаем, является родительским компонентом, который содержит 2 дочерних элемента: один - это Search
бар, включающий фильтры в виде раскрывающихся списков, а другой - SearchResultsList
, который отображает 4 Bootstrap - * 1024. * 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
компонент просто визуализирует поступающую пропу :people="filteredPeopleByKeyword"
Я надеюсь, что вышеизложенное имеет смысл и будет благодарен, если кто-нибудь идеи о том, как можно ускорить поиск, чтобы избежать или хотя бы минимизировать глюки? Приветствия