Cara Trendyol mengurangi INP sebesar 50%, yang menghasilkan peningkatan rasio klik-tayang sebesar 1%

Studi kasus ini menjelaskan alur kerja langkah demi langkah proses debug dan meningkatkan INP di React yang digunakan oleh Trendyol dengan memanfaatkan alat Google seperti PageSpeed Insights (PSI), Chrome DevTools, dan scheduler.yield API.

Dua komponen penting dari situs e-commerce adalah Halaman Listingan Produk (PLP) dan Halaman Detail Produk (PDP). Traffic e-commerce sering kali berasal dari halaman listingan produk, baik melalui kampanye email, media sosial, atau iklan. Oleh karena itu, pengalaman PLP harus dipastikan dengan cermat untuk mengurangi waktu yang diperlukan untuk melakukan pembelian. Memprioritaskan kualitas pengalaman pengguna sangat penting untuk mencapai kesuksesan. Publikasi riset seperti Milliseconds Make Millions telah mengungkap dampak performa web yang signifikan terhadap kesediaan konsumen untuk berbelanja dan berinteraksi dengan brand secara online.

Trendyol adalah platform e-commerce dengan sekitar 30 juta pelanggan dan 240.000 penjual. Hal ini mendorong kami untuk menjadi bisnis pertama di Turki dengan valuasi lebih dari $10 miliar, dan merupakan salah satu platform e-commerce teratas di dunia.

Untuk mencapai tujuannya dalam memberikan pengalaman pengguna sebaik mungkin dalam skala besar, sekaligus mempertahankan fleksibilitas konten dan menggunakan React versi lama, Trendyol berfokus pada Interaction to Next Paint (INP) sebagai metrik utama yang perlu ditingkatkan. Studi kasus ini menjelaskan perjalanan Trendyol dalam meningkatkan INP di PLP-nya, yang menghasilkan pengurangan INP sebesar 50% dan 1% peningkatan pada metrik bisnis hasil penelusuran.

Proses investigasi INP Trendyol

INP mengukur responsivitas situs terhadap input pengguna. INP yang baik menunjukkan bahwa browser dapat merespons semua input pengguna dengan cepat dan andal serta menggambar ulang halaman, yang merupakan komponen utama dari pengalaman pengguna yang baik.

Perjalanan Trendyol untuk meningkatkan INP pada PLP dimulai dengan analisis menyeluruh tentang pengalaman pengguna sebelum peningkatan apa pun dilakukan. Berdasarkan laporan PSI, pengalaman pengguna yang sebenarnya dari PLP memiliki INP 963 milidetik di perangkat seluler, seperti ditunjukkan pada gambar berikutnya.

INP Trendyol menurut pembacaan CrUX di PageSpeed Insights. INP Trendyol per 5 September 2023 adalah 963 milidetik, yang berada dalam rentang 'buruk'.
INP Trendyol per 5 September 2023 dari PSI.

Untuk memastikan responsivitas yang baik, pemilik situs harus menargetkan INP di bawah atau pada 200 milidetik yang berarti, pada saat itu, INP Trendyol berada dalam rentang "buruk".

Untungnya, PSI menyediakan data kolom untuk halaman yang disertakan dalam Laporan Pengalaman Pengguna Chrome (CrUX) dan data diagnostik lab yang mendetail. Dengan melihat data lab, audit waktu eksekusi JavaScript Lighthouse menunjukkan bahwa skrip search-result-v2 menempati thread utama lebih lama daripada skrip lain di halaman.

Pembacaan sumber tugas panjang di Lighthouse untuk situs Trendyol. Salah satu sumber utama tugas yang berjalan lama adalah skrip yang menangani hasil penelusuran di PLP Trendyol.
Audit Waktu Eksekusi JavaScript Trendyol dari Lighthouse per 5 September 2023 dari PSI.

Untuk mengidentifikasi bottleneck di dunia nyata, kami menggunakan panel performa di Chrome DevTools untuk memecahkan masalah pengalaman PLP dan mengidentifikasi sumber masalah. Mengemulasi performa seluler dengan pelambatan CPU 4X di Chrome DevTools mengungkapkan tugas berdurasi 700-900 milidetik di thread utama. Jika thread utama berisi tugas lain selama lebih dari 50 milidetik, thread utama mungkin tidak dapat merespons input pengguna secara tepat waktu, yang mengakibatkan pengalaman pengguna yang buruk.

Screenshot sesi pembuatan profil performa di Chrome DevTools untuk PLP Trendyol. Tugas panjang yang digambarkan berjalan selama 737,6 milidetik, dan merupakan bagian dari callback Intersection Observer.
Profiler performa untuk tugas yang berjalan lama di PLP Trendyol pada panel performa di Chrome DevTools.

Tugas terlama disebabkan oleh callback Intersection Observer API pada skrip hasil penelusuran di dalam komponen React. Di titik ini, kami mulai memecah tugas yang panjang menjadi potongan-potongan kecil agar browser memiliki lebih banyak peluang untuk merespons pekerjaan dengan prioritas lebih tinggi—termasuk interaksi pengguna.

Ternyata penggunaan operasi setState yang memicu rendering ulang React di dalam callback Intersection Observer menimbulkan biaya tinggi, dan dapat menimbulkan masalah untuk perangkat kelas bawah karena menempati thread utama terlalu lama.

Salah satu metode yang digunakan developer untuk membagi tugas menjadi tugas-tugas yang lebih kecil adalah setTimeout. Kami menggunakan teknik ini untuk menunda eksekusi panggilan setState ke tugas yang terpisah. Meskipun memungkinkan penundaan eksekusi JavaScript, setTimeout tidak memberikan kontrol apa pun atas prioritas. Hal ini mendorong kami untuk bergabung dengan uji coba origin scheduler.yield dalam upaya untuk menjamin kelanjutan eksekusi skrip kami setelah menyerah ke thread utama:

/*
* Yielding method using scheduler.yield, falling back to setTimeout:
*/
async function yieldToMain() {
  if('scheduler' in window && 'yield' in scheduler) {
    return await scheduler.yield();
  }

  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

/*
* Yielding to the main thread before changing the state of the component:
*/
const observer = new IntersectionObserver((entries) => {
  entries.forEach(handleIntersection);
  const maxNumberOfEntries = Math.max(...this.intersectingEntries);

  if (Number.isFinite(maxNumberOfEntries)) {
    await this.yieldToMain();

    this.setState({ count: maxNumberOfEntries });
  }
}, { threshold: 0.5 });

Menambahkan metode hasil ini ke kode PLP menghasilkan INP yang lebih baik, karena tugas panjang utama telah dibagi menjadi serangkaian tugas yang lebih kecil, sehingga memungkinkan pekerjaan dengan prioritas yang lebih tinggi—seperti interaksi pengguna dan pekerjaan rendering berikutnya—dapat dilakukan lebih cepat daripada seharusnya.

Screenshot sesi pembuatan profil performa di Chrome DevTools untuk PLP Trendyol. Tugas panjang yang sebelumnya berjalan selama 737,6 milidetik sekarang dibagi menjadi beberapa tugas yang lebih kecil.
Tugas dibagi menjadi tugas yang lebih kecil.

Perlu diperhatikan bahwa Trendyol menggunakan framework PuzzleJs untuk menerapkan arsitektur frontend mikro menggunakan React v16.9.0. Dengan React 18, performa yang sama dapat dicapai, tetapi karena sejumlah alasan, Trendyol saat ini tidak dapat melakukan upgrade.

Hasil bisnis

Untuk mengukur dampak peningkatan INP yang diterapkan, kami menjalankan pengujian A/B untuk melihat pengaruh terhadap metrik bisnis. Secara keseluruhan, perubahan kami pada PLP menghasilkan peningkatan yang signifikan, termasuk pengurangan INP sebesar 50% serta peningkatan rasio klik-tayang sebesar 1% dari halaman listingan ke halaman detail produk per sesi pengguna. Pada gambar berikut, Anda dapat melihat cara INP meningkatkan PLP dari waktu ke waktu:

Screenshot INP persentil ke-75 Trendyol selama enam bulan. Pada akhir enam bulan, INP Trendyol turun menjadi hampir 650 milidetik dari hampir 1.400 milidetik.
Peningkatan INP persentil ke-75 dari waktu ke waktu.

Kesimpulan

Mengoptimalkan INP adalah proses yang kompleks dan berulang, tetapi dapat dilakukan lebih mudah dengan alur kerja yang jelas. Pendekatan sederhana untuk men-debug dan meningkatkan INP situs Anda bergantung pada apakah Anda mengumpulkan data kolom Anda sendiri. Jika tidak, PSI dan Lighthouse adalah titik awal yang baik. Setelah mengidentifikasi halaman yang memiliki masalah, Anda dapat menggunakan DevTools untuk mempelajari lebih dalam guna mencoba mereproduksi masalah.

Dari waktu ke waktu, output ke thread utama akan memberikan lebih banyak peluang kepada browser untuk melakukan pekerjaan mendesak, yang akan membuat situs Anda lebih responsif, sehingga memastikan pelanggan memiliki pengalaman pengguna yang lebih baik. API penjadwalan yang lebih baru seperti scheduler.yield() membuat tugas ini lebih mudah.

Terima kasih banyak kepada Jeremy Wagner, Barry Pollard, dan Houssein Djirdeh dari Google, serta Tim Engineering Trendyol atas kontribusi mereka dalam upaya ini.