Я создаю приложение, которое взаимодействует с Spotify. Часть моего приложения — это FlatList экран, отображающий список песен и элементы управления песнями.
У меня сложилось впечатление, что мой FlatList очень плохо оптимизирован, что приводит к медленной загрузке при прокрутке вниз.
Основная проблема, которую я хочу решить, — это проблема с производительностью.
Во-первых, обертка аутентификации
import {
setAccessToken,
setRefreshToken,
} from '_redux/features/authenticationSlice'
import authHandler from '_utils/authenticationHandler'
async function updateReduxWithValidAccessToken({
accessToken,
accessExpiration,
refreshToken,
}) {
if (accessToken === null || new Date() > new Date(accessExpiration)) {
console.log('Access Token is Invalid, Refreshing...')
console.log('refreshToken=', refreshToken)
const response = await authHandler.refreshLogin(refreshToken)
accessToken = response.accessToken
setAccessToken({
accessToken,
accessExpiration: response.accessTokenExpirationDate,
})
setRefreshToken({
refreshToken: response.refreshToken,
})
}
return accessToken
}
Затем код загрузки песни. Это живет в компоненте
const [songs, setSongs] = useState([])
const [songsToFetch, setSongsToFetch] = useState(100)
const [page, setPage] = useState(0)
const getSongsOfPlaylist = async (aToken, aPlaylist, aPage, aLimit) => {
const response = await authHandler.get(
`/playlists/${aPlaylist}/tracks`,
aToken,
{
offset: 100 * aPage,
limit: aLimit,
fields:
'total,items(track(preview_url, id, name, duration_ms, artists, album(!available_markets)))',
},
)
if (response) {
const remainingSongs =
response.data.total - songs.length - response.data.items.length
setSongsToFetch(Math.min(100, remainingSongs))
setSongs([...songs, ...response.data.items])
}
}
Затем все функции, связанные с отрисовкой списка:
useEffect(() => {
console.log('Loading page #', page)
setLoading(true)
updateReduxWithValidAccessToken(authentication)
.then((token) => getSongsOfPlaylist(token, playlistID, page))
.then(() => {
setLoading(false)
})
}, [page])
async function loadMore() {
if (!loading && songsToFetch > 1) {
setPage(page + 1)
}
}
function renderFooter() {
if (!loading) {
return null
}
return <ActivityIndicator animating />
}
function renderSeparator() {
return <SeparatorLine />
}
Наконец, код плоского списка:
<MySongList
data={songs}
renderItem={renderListItem}
keyExtractor={(_, index) => index.toString()}
ItemSeparatorComponent={renderSeparator}
ListFooterComponent={renderFooter}
onEndReached={loadMore}
onEndReachedThreshold={0.1} />
Весь этот код (за исключением оболочки аутентификации) находится внутри компонента оболочки, PlaylistDetailScreen.
function PlaylistDetailScreen({ route, navigation, authentication, ...props }) {
// All code above
return loading && page === 0 ? (
<MyText> Loading... </MyText>
) : (
<ContainerView>
<MySongList />
<ContainerView />
)
Судя по моим усилиям, список перерисовывается несколько раз. Почему это могло быть?
