rbhz
← All posts

Published January 23, 2025 · 7 min read

Cara FlashList Optimasi List pada React Native

  • React Native
  • FlashList
  • Performance

This article is written in Indonesian.

Kalau kamu sering menggunakan React Native dan pernah pakai FlatList, mungkin pernah ngerasa performanya kurang oke kalau datanya cukup besar dan berat. Nah, FlashList adalah alternatif yang perfomanya sudah du tingkatkan sebagai solusi dari masalah yang ada pada Flatlist. Salah satu hal penting yang membuat FlashList lebih optimal adalah properti estimatedItemSize. Yuk, kita urai dan bahas bareng bareng mengenai per list-an pada React Native.

FlashList — swap from FlatList in seconds, get instant performance
Ilustrasi: Shopify — FlashList

Apa itu FlashList?

FlashList adalah library di React Native buat nge-handle list besar dengan performa yang lebih baik dibanding FlatList. Kalau FlatList kadang terasa berat pada data besar, FlashList ini lebih optimal karena cara kerjanya dalam menangani render data agak beda.

FlashList ini cocok untuk:

  • Data yang panjang: Misalnya ribuan item, misalkan saja.
  • Responsivitas tinggi: Scroll-nya tetap smooth walau data banyak.
  • Komponen kompleks: Kalau item di list punya banyak elemen.

Tapi, agar FlashList bisa maksimal, kita harus memberi tahu dia ukuran rata-rata item dalam list lewat properti estimatedItemSize, nanti kita akan urai lebih details mengenai estimatedItemSize sekarang kita lanjut pemabahasan dulu dikit.

FlatList vs FlashList: Apa Bedanya?

Meskipun kelihatannya mirip, ada beberapa perbedaan teknis penting antara FlatList dan FlashList dalam cara mereka merender data. Salah satunya adalah konsep VirtualizedLists yang menjadi inti dari cara kerja FlatList.

Perbandingan render FlatList vs FlashList
Ilustrasi: Shopify Engineering — FlatList vs FlashList

1. Cara Kerja FlatList dengan VirtualizedLists

FlatList dibangun di atas VirtualizedList, sebuah komponen di React Native yang dirancang untuk merender hanya sebagian kecil dari data yang terlihat di layar. Ide utamanya adalah mengurangi overhead dengan cara hanya menampilkan item yang benar-benar diperlukan (visible items) sementara item lainnya "dibuang" dari memori untuk menghemat resource. Mari kita ulas cara kerja flatlist.

Window Rendering. FlatList menentukan area yang dirender berdasarkan properti windowSize. Misalnya, jika windowSize adalah 21 (default), maka FlatList akan merender area layar utama (viewport height) ditambah 10 viewport di atas dan di bawahnya. Semakin besar nilai windowSize, semakin banyak item yang dirender sekaligus.

Recycling Components. Ketika kamu melakukan scroll, item yang keluar dari area visible akan dihapus dari DOM, dan komponen baru untuk item yang masuk area visible akan dirender ulang. Tapi proses ini bisa menjadi berat kalau ukuran window terlalu besar atau jika data punya struktur kompleks.

Masalah VirtualizedLists pada FlatList. Kalau list punya item dengan ukuran bervariasi, FlatList sering kali kesulitan memprediksi ukuran total dari list. Akibatnya, scroll bisa terasa tidak smooth karena FlatList mencoba menghitung ulang posisi dan ukuran item saat runtime.

2. Cara Kerja FlashList dalam mengoptimasi performance

FlashList dirancang untuk mengatasi kelemahan FlatList. Berikut adalah beberapa keunggulan yang di tawarkan:

Static Size Management. FlashList meminta developer memberikan nilai estimatedItemSize. Dengan ini, FlashList bisa menghitung jumlah item yang perlu dirender tanpa harus mengukur ukuran item secara dinamis. Hal ini mengurangi proses perhitungan di runtime, sehingga scroll terasa lebih smooth.

Dynamic Recycling. FlashList menggunakan suatu algoritma sebut saja reusing components, di mana komponen yang keluar dari viewport disimpan dalam pool dan dipakai ulang (reused) dengan data baru saat masuk kembali ke viewport. Ini mengurangi overhead pembuatan komponen baru. Misalkan saat user melakukan scroll, FlashList memantau posisi item yang berada di dalam buffer area (250px di atas dan di bawah viewport). Komponen yang sudah tidak diperlukan dalam buffer akan dihapus dari memori untuk menghemat resource. Komponen dalam pool diperbarui props-nya (misalnya data baru) tanpa harus membuat ulang instance komponen tersebut. Dengan cara ini, FlashList menjaga konsumsi memori tetap rendah sekaligus meningkatkan efisiensi rendering.

Optimized Rendering Boundaries. Tidak seperti FlatList yang merender area besar berdasarkan windowSize, FlashList hanya merender sekitar 250px di atas dan di bawah layar yang terlihat. Dengan batas render yang kecil, FlashList jauh lebih hemat memori tanpa mengorbankan responsivitas.

3. Pendekatan matematis dalam render data

FlatList. FlatList punya properti windowSize (default-nya 21). Ini artinya FlatList akan merender area layar yang terlihat (viewport height) ditambah 10 viewport di atas dan di bawah layar utama. Jadi, kalau tinggi layar device user 800px, FlatList akan merender area dengan contoh kalkulasi seperti ini:

800px (visible viewport height)
+ 10 × 800px (di atas)
+ 10 × 800px (di bawah)
= 16.800px total

Masalahnya adalah jika data sangat panjang, semakin banyak item yang dirender oleh FlatList, ini bisa menguras memori serta memperlambat performa.

FlashList. FlashList menggunakan pendekatan yang lebih hemat memori dengan hanya merender area kecil di atas dan di bawah layar yang terlihat (visible viewport). Default-nya adalah 250px ke atas dan 250px ke bawah. Jadi, jika layar utama adalah 800px, total area yang dirender oleh FlashList hanya:

800px (visible viewport)
+ 250px (di atas)
+ 250px (di bawah)
= 1.300px total

Dengan area render yang jauh lebih kecil, FlashList bisa menjaga performa tetap tinggi dan memori tetap efisien.

4. Perbedaan FlatList vs FlashList dalam Optimasi Memori

FlatList. Karena FlatList merender lebih banyak item daripada yang diperlukan (terutama untuk data panjang), ini membuat penggunaan memori jadi boros. Terutama kalau item di dalam list memiliki komponen yang kompleks, performa aplikasi bisa menurun drastis.

FlashList. FlashList hanya fokus merender item yang benar-benar perlu ditampilkan. Dengan mengurangi area render, FlashList menghemat memori sekaligus menjaga performa aplikasi tetap smooth.

Apa itu estimatedItemSize?

estimatedItemSize adalah properti untuk memberi tahu FlashList ukuran rata-rata item di dalam list yang akan di render. Dengan ini, FlashList bisa:

  • Nentuin berapa banyak item yang perlu dirender sekaligus.
  • Mengoptimalkan alokasi memori.
  • Meningkatkan responsivitas, terutama saat load awal atau scroll dengan cepat.

Cara Menghitung estimatedItemSize

Ada beberapa cara buat mendapatkan nilai yang proper untuk estimatedItemSize.

Kalau Ukuran Item Sama. Kalau semua item di list ukurannya sama (contohnya sebuah card item dengan tinggi tetap) maka:

  1. Gunakan Element Inspector dari React Native untuk melihat ukuran salah satu item.
  2. Masukkan ukuran itu langsung ke estimatedItemSize.
const estimatedItemSize = 100; // ukuran yang tidak berubah

Kalau Ukuran Item Berbeda. Kalau ukuran item bervariasi, maka bisa lakukan pendekatan berikut (agak effort dikit 😄):

  1. Pilih beberapa item dengan ukuran yang beda-beda.
  2. Gunakan Element Inspector untuk melihat ukuran masing-masing item.
  3. Hitung rata-ratanya.
const sizes = [120, 130, 140];
const estimatedItemSize =
  sizes.reduce((acc, size) => acc + size, 0) / sizes.length;
console.log(estimatedItemSize); // Output: 130

Gunakan Nilai yang Disarankan FlashList. Kalau kita tidak mengirim value untuk estimatedItemSize, FlashList akan memberi warning dan menyarankan sebuah nilai rata-rata berdasarkan render pertama, angka ini bisa kita copy dan set ke props estimatedItemSize. Tapi, tentu saja yang terbaik kita hitung dan tentukan sendiri agar lebih akurat.

Menggunakan Element Inspector React Native untuk mengukur item
Ilustrasi: dokumentasi FlashList (Shopify)

Efek estimatedItemSize pada Performance

Penggunaan estimatedItemSize secara langsung memengaruhi bagaimana FlashList merender item dalam list dan memanfaatkan resource memori. Berikut penjelasan rinci dampaknya:

1. Estimasi Terlalu Besar. Jika nilai estimatedItemSize lebih besar daripada ukuran rata-rata item sebenarnya, FlashList akan mengira jumlah item yang diperlukan lebih sedikit dari yang seharusnya. Saat kita scroll dengan cepat, mungkin akan muncul blank space karena FlashList tidak cukup cepat untuk mempersiapkan item tambahan. Ini bisa menyebabkan adanya area kosong pada layar sebelum item berikutnya dirender, tentu saja ini experience yang tidak baik bagi user, terutama pada device low-end.

2. Estimasi Terlalu Kecil. Jika nilai estimatedItemSize lebih kecil daripada ukuran rata-rata item sebenarnya, FlashList akan merender terlalu banyak item sekaligus. Ini dapat meningkatkan penggunaan memori secara signifikan. Aplikasi menjadi lebih lambat saat load awal karena terlalu banyak komponen yang dirender. Tentu Efek ini lebih terasa jika item dalam list memiliki komponen yang kompleks.

3. Estimasi yang Pas. Ketika nilai estimatedItemSize sesuai dengan rata-rata ukuran item, FlashList hanya akan merender jumlah item yang benar-benar diperlukan untuk viewport dan buffer area. Load time lebih cepat, scroll terasa lebih mulus, dan tidak ada blank space. Sehingga Konsumsi memori tetap efisien dan user experience menjadi lebih baik, terutama pada device low-end.

Sehingga, memilih nilai estimatedItemSize yang benar akan membantu FlashList bekerja lebih optimal dengan memaksimalkan performa dan tetap menjaga penggunaan resource tetap efisien.

Prediksi FlashList vs render dan update sebenarnya berdasarkan estimatedItemSize
Ilustrasi: dokumentasi FlashList (Shopify)

Contoh Implementasi FlashList dengan estimatedItemSize

Sekarang kita akan lihat contoh sederhana bagaimana menggunakan estimatedItemSize di FlashList:

import React from "react";
import { View, Text } from "react-native";
import { FlashList } from "@shopify/flash-list";

export default function ExampleFlashList() {
  const items = [
    { id: 1, title: "Item 1" },
    { id: 2, title: "Item 2" },
    { id: 3, title: "Item 3" },
  ];

  // Ukuran rata-rata item yang sudah dihitung sebelumnya
  const estimatedItemSize = 100;

  return (
    <FlashList
      data={items}
      renderItem={({ item }) => (
        <View
          style={{
            height: 100, // Sesuai dengan estimatedItemSize
            justifyContent: "center",
            alignItems: "center",
          }}
        >
          <Text>{item.title}</Text>
        </View>
      )}
      keyExtractor={(item) => item.id.toString()}
      estimatedItemSize={estimatedItemSize}
    />
  );
}

Nah segitu aja pembahasan kita mengenai Flatlist dan Flashlist. Semoga membantu dalam meningkatkan performa App kalian ya, karena percuma aplikasi bagus kalau performa buruk, user pasti jengkel untuk menggunakan aplikasi kita.

Thank you.. see you on the next topic. 🫡

Originally published on Medium ↗

Get in touch

Building something that has to ship?

Whether it's a rewrite, a mobile architecture call, a talk for your community, or just comparing notes on React Native at scale — I'm happy to talk.