Мне интересно, как улучшить производительность и уменьшить ненужные повторные ресурсы или отображение/фильтрацию.
Обзор приложения: < /p>
У меня есть нативное приложение React для управления задачами или более простое приложение Todos. < /p>
Пользователь может создать несколько списков со многими задачами. Задачи имеют крайний срок, статус завершения и другие свойства. Списки являются объектом, и каждый список содержит элементы, которые также являются объектами. />
Код: Выделить всё
{
"1737818490661": {
"id": 1737818490661,
"title": "Title",
"description": "Description",
"createdAt": "2025-01-25T15:21:30.661Z",
"deadline": null,
"completed": false,
"progress": 0,
"showListsDeadline": false,
"showProgressBar": false,
"showCompleted": false,
"showOriginalIndex": false,
"items": {
"1737818490662": {
"id": 1737818490662,
"title": "Task Title",
"completed": false,
"listId": 1737818490661,
"latinized": "Task Title",
"itemDeadline": "2025-01-27T15:22:00.000Z"
},
"1737905755884": {
"title": "Task Title 2",
"latinized": "Task Title 2",
"completed": false,
"id": 1737905755884,
"listId": 1737818490661
},
},
"latinized": "Title",
"lastActivity": "2025-01-27T09:19:42.674Z",
"currentItemSort": "index",
"listLength": 4,
"closestItemDeadline": "2025-01-27T15:22:00.000Z"
}
}
В основном компоненте списки отображаются в массив для отображения в FlatList.
ListItem содержит объект items, который отображается в массив и лишен большинства значений, кроме заголовка и идентификатора. Доступ к остальным значениям осуществляется через lists[listId].items[itemId]
ПОЧЕМУ?
- FlatList отображает элементы по идентификатору, то есть, если элемент изменяется, ему не нужно повторно отображать весь список. Внутри этого элемента данные get() из хранилища. // но данные необходимо изначально сопоставить
- списки и элементы хранятся как объекты для облегчения доступа. Очевидно, find() требует очень большой производительности // но данные списков необходимо сопоставлять при каждом изменении
Код: Выделить всё
const List = () => {
const rawLists = useZustandStore(state => state.lists)
const currentSort = useZustandStore(state => state.currentSort)
const showCompleted = useZustandStore(state => state.showCompletedLists)
const searchQuery = useSelector(selectors.selectSearch)
const renderList = useCallback(
({ item }) => ,
[],
)
const lists = useMemo(
() =>
Object.keys(rawLists)
.map((key, index) => ({
id: key,
...rawLists[key],
items: Object.values(rawLists[key].items),
itemIndex: index + 1,
}))
.sort((a, b) => a.id - b.id),
[rawLists],
)
const searchList = (items, query) => {
if (!query) {
return null
}
const lowerLatinQuery = latinize(query?.toLowerCase())
return items.filter(item => {
return (
item.latinized.toLowerCase().includes(lowerLatinQuery) ||
item?.description?.toLowerCase().includes(lowerLatinQuery) ||
item?.items?.some(subItem =>
subItem?.latinized?.toLowerCase().includes(lowerLatinQuery),
)
)
})
}
const sortedLists = useSortedLists({ currentSort, lists })
const filteredLists = useMemo(() => {
return sortedLists.filter(item => showCompleted || !item.completed)
}, [sortedLists, showCompleted])
const queriedItems = searchList(sortedLists, searchQuery)
return (
)
}
const ListItem = ({
route
}) => {
const lists = useZustandStore(state => state.lists)
const itemIdParams = route.params?.item?.id
const list = lists[itemIdParams]
const listId = list?.id
const currentItemSort = list?.currentItemSort
const showCompleted = list?.showCompleted || false
const showOriginalIndex = list?.showOriginalIndex || false
const itemsAsObjects = list?.items
const {
arrayOfItemIds,
arrayOfAllItems,
nonCompletedItems,
lastItemExistsAndHasTitle,
} = useMemo(() => {
const arrayOfItemIds = []
const arrayOfAllItems = []
const nonCompletedItems = []
let lastItemId = null
if (itemsAsObjects) {
Object.keys(itemsAsObjects).forEach((key, index) => {
const item = itemsAsObjects[key]
const listId = itemsAsObjects[key]?.listId
const strippedItem = {
id: key,
listId,
itemIndex: index + 1,
}
arrayOfItemIds.push(strippedItem)
arrayOfAllItems.push({
...item,
listId,
itemIndex: index + 1,
})
if (!item.completed) {
nonCompletedItems.push(strippedItem)
}
if (item.completed) {
completedCount++
}
lastItemId = key
})
arrayOfItemIds.sort((a, b) => a.id - b.id)
nonCompletedItems.sort((a, b) => a.id - b.id)
}
return {
arrayOfItemIds,
arrayOfAllItems,
nonCompletedItems,
lastItemId,
lastItemExistsAndHasTitle,
}
}, [itemsAsObjects])
const searchItems = (items, query) => {
if (!query) {
return null
}
const lowerLatinQuery = latinize(query?.toLowerCase())
return items.filter(item => {
return item.latinized.toLowerCase().includes(lowerLatinQuery)
})
}
const queriedItems = searchItems(arrayOfAllItems, searchQuery)
const sortedItems = useSortedItems({
currentSort: currentItemSort || 'index',
items: arrayOfAllItems,
completed: showCompleted,
})
const renderItem = useCallback(
({
item,
index
}) => {
return ( <
ItemWithActions item = {
item
}
index = {
index
}
listId = {
listId
}
showCompleted = {
showCompleted
}
showOriginalIndex = {
showOriginalIndex
}
arrayOfItemIdsLength = {
arrayOfItemIds.length
}
nonCompletedItemsLength = {
nonCompletedItems.length
}
/>
)
},
[
listId,
showCompleted,
showOriginalIndex,
arrayOfItemIds.length,
nonCompletedItems.length,
],
)
return ( <
KeyboardAwareFlatList as = {
Animated.FlatList
}
data = {
searchQuery ? queriedItems : sortedItems
}
renderItem = {
renderItem
}
keyExtractor = {
keyExtractor
}
/>
)
}< /code>
< /div>
< /div>
< /p>
Если вы читаете фрагменты, вы видите, что данные отформатированы много раз прежде чем он будет отображаться. Разделение предметов значений выглядит как хорошая идея, но мне все еще нужны разделенные значения в случае, если пользователь использует строку поиска для просмотра заголовков. Точно так же с списками. < /P>
Все ли эти расчеты необходимы? Должен ли я использовать массивы или объекты? Их в одном списке (или 3 в этом случае) Если я создаю эти списки, фильтраруя, они должны будут пересматриваться каждый раз, когда что -то меняется, по мере изменения корневого объекта. Как не потерять производительность?>
Подробнее здесь: https://stackoverflow.com/questions/793 ... ssing-data