Meningkatkan Penggunaan Memori Front-End hingga 30 Kali Lipat pada Pemuatan Carousel

Pada kuartal kedua tahun 2020, kami melakukan refaktorisasi teknis pada halaman pengalaman, dengan menulis ulang menggunakan React dan mengintegrasikan REST API. Namun, selama implementasi, kami menemukan masalah yang menarik.
Ada sekitar 20 carousel di halaman pengalaman, masing-masing dengan setidaknya 60 ubin. Jadi, halaman tersebut akan menampilkan lebih dari 1.200 pengalaman, termasuk informasi relevan seperti judul, peringkat pengguna, pengguna bersamaan, dan thumbnail. Di setiap carousel, mengklik gulir ke kanan akan mengirimkan permintaan untuk memuat kumpulan pengalaman berikutnya jika masih ada. Kemudian, data baru yang dihasilkan dari permintaan tersebut akan ditambahkan ke carousel, yang berarti lebih banyak node ditambahkan ke dalam DOM dan lebih banyak thumbnail yang ditampilkan di browser. Penggunaan memori di dalam browser akan meningkat saat pengguna menggulir untuk meminta lebih banyak data, dan kemudian UX akan melambat dan mulai tersendat.

Profil Memori
Kita dapat menggunakan Chrome Developer Tools untuk memprofilkan masalah ini. Snapshot pertama diambil saat halaman pertama kali dimuat, dan yang kedua diambil setelah pengguna mengklik tombol gulir berikutnya di satu carousel sebanyak 12 kali. Kita melihat peningkatan penggunaan memori hampir 9,7 MB akibat lebih dari 100 node string dan peningkatan rendering thumbnail.

Solusi
Saat carousel bergulir, pengguna hanya melihat item dari jendela carousel. Misalnya, pada laptop dengan resolusi 1920×1080, dalam mode layar penuh browser, hanya akan ada ~9 item yang terlihat setiap kali. Oleh karena itu, tidak perlu merender semua node dan thumbnail yang tidak terlihat sekaligus atau membawa lebih banyak data yang dikembalikan dari permintaan ke dalam DOM.
Jadi, begini ide dasarnya: setelah kita mengambil data mentah dari permintaan API untuk pertama kali, kita membangun array dengan panjang yang sama untuk persiapan rendering ke dalam DOM. Di dalam array rendering, kita hanya mengisi data secukupnya untuk mengisi tampilan dan menggulir ke item berikutnya. Sisanya akan diisi hanya ketika jendela tampilan digulir mendekati bagian tersebut. Mari kita gunakan dua indeks untuk mencatat rentang data rendering: renderingStartIndex dan renderingEndIndex. Kita mengatur kursor untuk menunjukkan posisi awal mana di daftar yang terlihat. Saat menggulir, kita perlu terus memperbarui kursor ke indeks item pertama yang terlihat. Sebelum animasi pengguliran selesai, kita perlu memeriksa apakah kursor berikutnya berada di dalam array data rendering. Berdasarkan ukuran jendela carousel dan ukuran kartu, kita dapat dengan mudah menentukan berapa banyak item yang terlihat yang akan muat di jendela tampilan. Kemudian, kita perlu memastikan bahwa item dari jendela saat ini dan jendela berikutnya berada di dalam rentang array data rendering. Jika tidak, kita mengambil item dari data mentah untuk mengisi daftar kosong sambil juga menghapus data sebelum posisi kursor. Hal ini berlaku saat pengguna menggulir ke kanan atau kiri. Saat pengguna menggulir ke kanan, dengan mengambil lebih banyak data di latar belakang, kami akan mengisi data mentah setiap kali setelah kami menerima data baru. Namun, data mentah tidak akan terlibat dalam rendering halaman.


Profil Memori
Mari kita lihat kembali Chrome Developer Tools. Seperti sebelumnya, snapshot pertama diambil pada saat inisialisasi dan yang kedua diambil setelah menggulir ke kanan sebanyak 12 kali. Sekarang, memuat 100+ item hanya membutuhkan tambahan memori sebesar 0,3MB, dibandingkan dengan 9,7MB sebelumnya.

Apa Selanjutnya?
Selain meningkatkan komponen carousel untuk menangani jendela data yang besar, saat kita melakukan refaktorisasi fitur/halaman, kita perlu menambahkan lebih banyak tolok ukur untuk mengumpulkan informasi kinerja.
Meskipun tumpukan aplikasi web modern telah bergeser ke arah front-end, menangkap dan meningkatkan telemetri front-end sama pentingnya dengan telemetri back-end tradisional.
Ying Jiang adalah Insinyur Perangkat Lunak Frontend Utama di Roblox. Sebagai Insinyur Frontend pertama di Roblox, ia berupaya memperkenalkan tumpukan teknologi frontend modern ke dalam Roblox serta meningkatkan alur kerja pengembangan dan penerapan. Ia juga telah mengerjakan fitur-fitur real-time seperti obrolan, aliran notifikasi, dan suara.
Baik Roblox Corporation maupun blog ini tidak mendukung atau mengendorse perusahaan atau layanan apa pun. Selain itu, tidak ada jaminan atau janji yang diberikan terkait keakuratan, keandalan, atau kelengkapan informasi yang terkandung dalam blog ini.


