가상화 리스트:업데이트 속도가 느린 목록이 많습니다.
Flat List는 아이템이 많은 것을 사용하고 있습니다.엑스포 XDE에서 다음과 같은 경고를 받았습니다.
가상화 리스트:업데이트가 느린 목록이 많습니다.renderItem 함수가 PureComponent, wouldComponentUpdate 등의 리액트 성능 모범 사례를 따르는 컴포넌트를 렌더링해야 합니다.{ "dt " : 13861 " prevDt " : 1498372326027 " contentLength " : 6624 }
FlatList에 대해 PureComponent와 같은 최적화 방법을 사용했지만 여전히 이 경보가 표시됩니다.최적화를 설명하기 전에 FlatList가 최적화되어 있어도 이 경보가 항상 표시되는지 알려 주시겠습니까?아니면 퍼포먼스에 관한 실제적인 문제를 나타내고 있었을까요?FlatList의 성능이 좋기 때문에 물어봅니다.
이전에 이 에러가 발생하고 있었습니다.코드를 최적화하면 더 이상 표시되지 않습니다.FlatList를 작성하는 컴포넌트의 render() 함수와 목록 내의 각 항목을 렌더링하는 함수에 console.log() 문을 추가하여 문제를 파악했습니다.이 페이지의 컴포넌트(FlatList와 관련이 없는 컴포넌트라도)에 상태 변화가 있을 때마다 코드가 FlatList 전체와 모든 항목을 다시 렌더링하고 있는 것을 알 수 있었습니다.다양한 컴포넌트를 Pure Components로 변환하여 수정하였습니다.FlatList 선언은 다음과 같습니다.
<FlatList
ref={(ref) => { this.flatListRef = ref; }}
data={allPosts}
initialNumToRender={7}
renderItem={({ item }) =>
<Post postJson={item} isGroupAdmin={isGroupAdmin} user={user} />
}
/>
가 것을 하세요.<Post />
순수한 구성요소입니다.
import React, { PureComponent } from 'react';
class Post extends PureComponent {
render() { ... }
}
이렇게 하면 게시물이 변경된 경우에만 FlatList가 다시 렌더링됩니다.에 일반 를 to전에 했을 때renderItem
이렇게입니다.
return (
<View>
...
</View>
);
Flat List는 아이템이 변경될 때마다 모든 아이템을 재렌더하고 있는 것을 알 수 있었습니다.이제 Pure Component를 사용하면 FlatList는 목록에 추가된 새 항목만 렌더링합니다(리스트가 이미 표시되어 있는 경우).
전체 목록을 처음 렌더링하는 데는 여전히 시간이 오래 걸립니다. ★★★★★★★★★★★★★★.initialNumToRender
나머지 항목이 백그라운드로 렌더링되는 동안 화면이 즉시 채워지도록 합니다.그리고 무엇보다 첫 번째 렌더링 후 FlatList는 한 번에 하나의 항목(변경되는 항목)만 렌더링하면 됩니다.
여기에도 설명되어 있다는 것을 방금 깨달았습니다.
이 질문에 대한 답변은 기능적인 컴포넌트와 후크를 사용하는 사용자에게는 솔루션 제공이 되지 않는다는 것을 알게 되었습니다.이 문제가 발생하여 useMemo() 후크를 사용하여 제거할 수 있었습니다.
<FlatList
keyExtractor={keyExtractor}
data={productsState.products}
renderItem={renderItem}
/>
const renderItem = ({ item }) => (
<ListItem
title={item.ProductName}
subtitle={(item.ProductQuantity) + " " + (item.QuantityType !==
null ? item.QuantityType : " ") }
bottomDivider
topDivider
chevron
checkmark={checkMark}
onLongPress={() => setCheckMark(!checkMark)}
rightSubtitle={(item.Currency !== null ? item.Currency: " " ) +
" " + (item.productCost !== null ? item.productCost: " " )}
rightSubtitleStyle={{ marginTop: -20 }}
badge={{ value: item.sellingPrice, textStyle: { color: 'orange' }, containerStyle: { marginTop: -20 } }}
/>
)
renderItem 함수는 렌더링할 목록이 길기 때문에 계산 비용이 많이 듭니다.대신 다음과 같이 메모합니다.
const memoizedValue = useMemo(() => renderItem, [productsState.product]);
<FlatList
keyExtractor={keyExtractor}
data={productsState.products}
renderItem={memoizedValue}
/>
const renderItem = ({ item }) => (
<ListItem
title={item.ProductName}
subtitle={(item.ProductQuantity) + " " + (item.QuantityType !==
null ? item.QuantityType : " ") }
bottomDivider
topDivider
chevron
checkmark={checkMark}
onLongPress={() => setCheckMark(!checkMark)}
rightSubtitle={(item.Currency !== null ? item.Currency: " " ) +
" " + (item.productCost !== null ? item.productCost: " " )}
rightSubtitleStyle={{ marginTop: -20 }}
badge={{ value: item.sellingPrice, textStyle: { color: 'orange' }, containerStyle: { marginTop: -20 } }}
/>
)
이 작업을 수행하려면 react에서 useMemo를 Import하는 것을 잊지 마십시오.
행운을 빕니다.
컴포넌트를 를 the the the the로 .memo
는 기능 컴포넌트를 순수 클래스 컴포넌트로 변환하는 번거로움을 겪지 않고 불필요한 렌더링을 방지하는 좋은 방법입니다.이 투고에서 자세히 설명합니다.
다음 예를 따릅니다.
부모 컴포넌트:
import React from 'react';
import {FlatList} from 'react-native';
import PostCard from './PostCard';
export const NewsFeeds = props => {
return (
<FlatList
data={data}
initialNumToRender={4}
refreshing={loading}
renderItem={_renderitem}
/>
);
};
const _renderitem = ({item}) => <PostCard item={item} />;
하위 구성 요소
import React, {memo} from 'react';
import {View} from 'react-native';
const PostCard = (props) => {
return (
<View>
</View>
);
};
export default memo(PostCard);
컴포넌트를 합니다.React. PureComponent
class NewsFeeds extends React.PureComponent {
render() {
return (
<FlatList
data={data}
initialNumToRender={4}
refreshing={loading}
renderItem={_renderitem}
/>
)
}
}
이 소품 추가:
initialNumToRender={n}
요. (서양속담, 일속담)n
(어: 5)라고 하다
왜 이 버그가 발생하는지 알아냈어요.가장 큰 문제는 OnEndReached 이벤트가 발생했을 때 서버에서 로딩하고 있는 것이 확실하다는 것입니다.즉, 서버에서 로딩이 완료될 때까지 기다렸다가 OnEndReached 이벤트를 호출할 수 있습니다.
단, 고객님의 경우 OnEndReached 이벤트의 멀티플 콜이 있습니다.이 경우 어플리케이션은 서버에서 데이터를 몇 번이고 로드하려고 했습니다.
이 문제를 해결하려면 새로운 상태를 만들어야 합니다. 예를 들어 페이지 번호에 의한 무한 스크롤을 실현하는 것입니다.
const [loader, setLoader] = useState<boolean>(false);
const onEndReached = (page) => {
if (next && !loader) {
setPage(page + 1)
}
}
const loadData = async () => {
setLoader(true);
const resp = await getData();
setLoader(false);
}
<FlatList ...someprops onEndReached={onEndReached} />
이 모든 설정해 볼 수도 .removeClippedSubviews
로로 합니다.true
.
<FlatList
removeClippedSubviews
// ...other props
/>
효효게 by by by를 유효하게 removeClippedSubviews
항목이 보기에서 사라지면 메모리가 해방됩니다.길고 복잡한 리스트(카드 리스트 등)가 있는 경우, 각 카드의 DOM 는 매우 커질 가능성이 있기 때문에, 표시되지 않을 때는 메모리를 해방하는 것이 가장 좋습니다.
, 음, 음, 음, 음, 음, 음, 다, with, with, in, in, in, in, in, in, in.useCallback()
useMemo()
가 바뀌면 더 가 생깁니다.
const renderItem = useCallback(originalRenderItem, [data])
useMemo()
접근법은 값에 따라 메모화되지만 데이터가 변경되면 완전히 해방됩니다.useCallback()
'파라미터로서의 기능'을 사용할 수 있는 이점을 얻을 필요가 없습니다.
const renderItem = useCallback(({item, index}
=> originalRenderItem({item, index}), [data])
따라서 다음 사람이 읽을 수 있는 만큼 읽지 않고 마치 포장된 기능처럼 보이게 할 수 있습니다.
이 두 가지 작업을 수행합니다.
- 비용이 많이 드는 콜을 방지하다
render()
최신 업데이트 컴포넌트 기능 - 보이지 않는 컴포넌트에서 사용되는 메모리를 줄입니다.
- 메모화된 데이터를 해방하는 경우
data
더 빨리 변화합니다.
또한 FlatList를 ScrollList로 캡슐화하지 마십시오.네이티브 베이스를 사용했는데 몰랐기 때문에 우연히 컴포넌트가<Content>
Scroll List를 바꿉니다.
상세한 것에 대하여는, https://stackoverflow.com/a/54512633/1256697 를 참조해 주세요.
내보낼 때 renderItem 구성 요소에 메모 추가
"react"에서 {memo}을(를) Import하고, 코드를... 기본 메모(컴포넌트 이름)를 내보냅니다.
언급URL : https://stackoverflow.com/questions/44743904/virtualizedlist-you-have-a-large-list-that-is-slow-to-update
'programing' 카테고리의 다른 글
커스텀 에이잭스를 적절히 구현하는 방법 (0) | 2023.02.23 |
---|---|
레독스 저장소의 중첩된 데이터 업데이트 (0) | 2023.02.23 |
Angular에서의 $modal 조롱JS 유닛 테스트 (0) | 2023.02.23 |
.forEach()가 완료될 때까지 기다리는 가장 좋은 방법 (0) | 2023.02.23 |
특정 국가의 Chrome에서 word press err_connection_reset을 누릅니다. (0) | 2023.02.23 |