programing

가상화 리스트:업데이트 속도가 느린 목록이 많습니다.

subpage 2023. 2. 23. 22:48
반응형

가상화 리스트:업데이트 속도가 느린 목록이 많습니다.

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

반응형