Przejdź do treści głównej
Wersja: 0.78

Optymalizacja konfiguracji FlatList

Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

Terminy

  • VirtualizedList: Komponent stojący za FlatList (implementacja koncepcji Virtual List w React Native)

  • Memory consumption (Zużycie pamięci): Ilość informacji o twojej liście przechowywanych w pamięci, co może prowadzić do awarii aplikacji

  • Responsiveness (Reaktywność): Zdolność aplikacji do reagowania na interakcje. Niska reaktywność występuje na przykład wtedy, gdy dotkniesz komponentu, a on zwleka z reakcją zamiast odpowiedzieć natychmiast

  • Blank areas (Puste obszary): Kiedy VirtualizedList nie może renderować elementów wystarczająco szybko, możesz trafić na część listy z nierenderowanymi komponentami wyświetlanymi jako puste przestrzenie

  • Viewport: Widoczny obszar treści renderowanej do pikseli

  • Window (Okno): Obszar, w którym elementy powinny być zamontowane, zazwyczaj znacznie większy niż viewport

Właściwości

Oto lista właściwości, które mogą pomóc poprawić wydajność FlatList:

removeClippedSubviews

TypeDefault
Booleantrue on Android, otherwise false

Jeśli ustawione na true, widoki poza obszarem viewportu są automatycznie odłączane od natywnej hierarchii widoków.

Zalety: Zmniejsza czas spędzany na głównym wątku, redukując ryzyko opuszczonych klatek, poprzez wykluczenie widoków poza viewportem z natywnych przejść renderowania i rysowania

Wady: Ta implementacja może powodować błędy, np. brakujące treści (głównie na iOS), szczególnie przy skomplikowanych transformacjach i/lub pozycjonowaniu absolutnym. Nie oszczędza znacząco pamięci, bo widoki są tylko odłączane, a nie dealokowane

maxToRenderPerBatch

TypeDefault
Number10

Właściwość VirtualizedList przekazywana przez FlatList. Kontroluje liczbę elementów renderowanych w partii - kolejnym fragmencie renderowanym przy każdym przewijaniu

Zalety: Większa wartość oznacza mniej pustych obszarów podczas przewijania (zwiększa współczynnik wypełnienia)

Wady: Więcej elementów na partię oznacza dłuższe wykonywanie JavaScriptu, potencjalnie blokujące inne zdarzenia (np. dotknięcia), co pogarsza reaktywność

updateCellsBatchingPeriod

TypeDefault
Number50

Podczas gdy maxToRenderPerBatch określa liczbę elementów na partię, ustawienie updateCellsBatchingPeriod definiuje dla twojej VirtualizedList opóźnienie (w milisekundach) między renderowaniami partii (częstotliwość renderowania elementów w oknie)

Zalety: Połączenie z maxToRenderPerBatch daje kontrolę np. nad renderowaniem więcej elementów rzadziej lub mniej elementów częściej

Wady: Rzadsze partie mogą powodować puste obszary, częstsze - problemy z reaktywnością

initialNumToRender

TypeDefault
Number10

Początkowa liczba elementów do renderowania

Zalety: Precyzyjne określenie liczby elementów pokrywających ekran na każdym urządzeniu. Może znacząco przyspieszyć początkowy render

Wady: Zbyt niska wartość initialNumToRender może powodować puste obszary, szczególnie jeśli nie pokryje viewportu przy początkowym renderowaniu

windowSize

TypeDefault
Number21

Wartość liczbowa gdzie 1 odpowiada wysokości viewportu. Domyślnie 21 (10 viewportów powyżej, 10 poniżej i jeden pośrodku)

Zalety: Większy windowSize zmniejsza ryzyko pustych obszarów przy przewijaniu. Mniejszy windowSize ogranicza liczbę jednocześnie montowanych elementów, oszczędzając pamięć

Wady: Większy windowSize zwiększa zużycie pamięci. Mniejszy windowSize zwiększa ryzyko pustych obszarów

Elementy listy

Poniżej znajdują się wskazówki dotyczące komponentów elementów listy. Stanowią one trzon Twojej listy, dlatego muszą być szybkie.

Używaj podstawowych komponentów

Im bardziej skomplikowane są Twoje komponenty, tym wolniej będą się renderować. Staraj się unikać dużej ilości logiki i zagnieżdżania w elementach listy. Jeśli często używasz tego samego komponentu elementu listy w swojej aplikacji, utwórz komponent przeznaczony tylko do dużych list i zrób go z jak najmniejszą ilością logiki i zagnieżdżania.

Używaj lekkich komponentów

Im cięższe są Twoje komponenty, tym wolniej się renderują. Unikaj ciężkich obrazów (używaj przyciętej wersji lub miniatury dla elementów listy, tak małych jak to możliwe). Porozmawiaj ze swoim zespołem projektowym, używaj jak najmniej efektów, interakcji i informacji na liście. Pokaż je w szczegółach elementu.

Używaj memo()

React.memo() tworzy zmemoizowany komponent, który będzie ponownie renderowany tylko wtedy, gdy zmienią się właściwości przekazane do komponentu. Możemy użyć tej funkcji do optymalizacji komponentów w komponencie FlatList.

tsx
import React, {memo} from 'react';
import {View, Text} from 'react-native';

const MyListItem = memo(
({title}: {title: string}) => (
<View>
<Text>{title}</Text>
</View>
),
(prevProps, nextProps) => {
return prevProps.title === nextProps.title;
},
);

export default MyListItem;

W tym przykładzie ustaliliśmy, że MyListItem powinien być ponownie renderowany tylko wtedy, gdy zmieni się tytuł. Przekazaliśmy funkcję porównującą jako drugi argument do React.memo(), aby komponent był ponownie renderowany tylko wtedy, gdy zmieni się określona właściwość. Jeśli funkcja porównująca zwróci wartość true, komponent nie zostanie ponownie wyrenderowany.

Używaj buforowanych zoptymalizowanych obrazów

Można użyć pakietów społecznościowych (takich jak @d11/react-native-fast-image od Dream11) w celu uzyskania wydajniejszych obrazów. Każdy obraz na liście to instancja new Image(). Im szybciej osiągnie hook loaded, tym szybciej wątek JavaScript zostanie zwolniony.

Używaj getItemLayout

Jeśli wszystkie komponenty elementów listy mają tę samą wysokość (lub szerokość, w przypadku listy poziomej), dostarczenie właściwości getItemLayout eliminuje konieczność zarządzania asynchronicznymi obliczeniami układu przez FlatList. Jest to bardzo pożądana technika optymalizacji.

Jeśli Twoje komponenty mają dynamiczny rozmiar i naprawdę potrzebujesz wydajności, rozważ poproszenie zespołu projektowego o przemyślenie redesignu w celu poprawy wydajności.

Używaj keyExtractor lub key

Możesz ustawić keyExtractor dla swojego komponentu FlatList. Ta właściwość jest używana do buforowania oraz jako Reactowy key do śledzenia zmiany kolejności elementów.

Możesz również użyć właściwości key w swoim komponencie elementu.

Unikaj anonimowych funkcji w renderItem

W przypadku komponentów funkcyjnych przenieś funkcję renderItem poza zwracany JSX. Upewnij się także, że jest ona opakowana w hook useCallback, aby zapobiec jej ponownemu tworzeniu przy każdym renderowaniu.

W przypadku komponentów klasowych przenieś funkcję renderItem poza funkcję render, aby nie była ona ponownie tworzona za każdym razem, gdy wywoływana jest funkcja render.

tsx
const renderItem = useCallback(({item}) => (
<View key={item.key}>
<Text>{item.title}</Text>
</View>
), []);

return (
// ...

<FlatList data={items} renderItem={renderItem} />;
// ...
);