Case Study

Studi Kasus Nalesha: Turunkan CLS dari 0,28 ke 0,04 dengan Grid Reservation di Product Listing 2026

Vito Atmo
Vito Atmo·25 Mei 2026·0 kali dibaca·4 min baca
Studi Kasus Nalesha: Turunkan CLS dari 0,28 ke 0,04 dengan Grid Reservation di Product Listing 2026

TL;DR: Halaman product listing Nalesha mencatat CLS 0,28 di mobile, karena gambar produk lazy-load tanpa reservasi ruang. Setelah pasang CSS aspect-ratio dan min-height di grid container, CLS turun ke 0,04 dalam 7 hari pengukuran field data CrUX. Total perubahan kode: 38 baris.

Nalesha adalah e-commerce parfum lokal yang dibangun di Next.js 15 App Router. Bulan lalu tim mereka melaporkan keluhan: ranking halaman katalog turun di Google meskipun konten tidak berubah. Setelah cek Search Console, sumber masalahnya jelas. Core Web Vitals report mencatat CLS halaman /koleksi di kategori "perlu perbaikan" dengan p75 sebesar 0,28.

Studi kasus ini menjelaskan apa yang ditemukan, perubahan yang dilakukan, dan hasil pengukuran setelah perbaikan.

Diagnosis Awal: Lazy-Load Tanpa Reservasi

Halaman /koleksi menampilkan grid 12 produk per viewport dengan gambar produk 4:5. Kode listing waktu itu:

tsx
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
  {products.map(p => (
    <article key={p.id}>
      <Image src={p.image} alt={p.name} width={400} height={500} loading="lazy" />
      <h3>{p.name}</h3>
      <p>{p.price}</p>
    </article>
  ))}
</div>

Sekilas terlihat benar: width dan height sudah diset, loading="lazy" aktif. Tapi yang luput, container grid tidak punya reservasi tinggi. Saat gambar lazy-load triggered scroll, layout shift terjadi karena tiap baris baru mendorong konten footer ke bawah. Selain itu, Image dari next/image membungkus dengan div wrapper yang ukurannya tidak fixed di mobile karena Tailwind w-full default.

Pengukuran lab Lighthouse mencatat 9 layout shift event di scroll pertama, total skor CLS 0,31.

Framework Perbaikan: 3 Lever CLS

LeverTeknikDampak
1. Aspect-ratioSet aspect-ratio: 4/5 di wrapper imageBrowser reservasi tinggi sebelum gambar load
2. Min-height grid itemTetapkan minimum tinggi card via CSSAntisipasi varian tinggi teks produk
3. Image prioritySet priority untuk 4 produk pertama (above-the-fold)Tidak lazy-load yang sudah pasti di viewport

Detail teknis soal aspect-ratio dan reservasi dimensi ada di dokumentasi CLS optimization web.dev.

Implementasi: 38 Baris Perubahan

tsx
// app/koleksi/page.tsx
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
  {products.map((p, idx) => (
    <article key={p.id} className="min-h-[380px]">
      <div className="aspect-[4/5] relative overflow-hidden">
        <Image
          src={p.image}
          alt={p.name}
          fill
          sizes="(min-width: 768px) 25vw, 50vw"
          priority={idx < 4}
          loading={idx < 4 ? "eager" : "lazy"}
        />
      </div>
      <h3 className="mt-2 line-clamp-2">{p.name}</h3>
      <p className="font-semibold">{p.price}</p>
    </article>
  ))}
</div>

Tiga perubahan kunci: wrapper aspect-[4/5] di gambar (reservasi rasio), min-h-[380px] di article (reservasi tinggi card), line-clamp-2 di nama produk (cegah varian tinggi 1 vs 2 baris). Untuk 4 produk pertama, priority aktif supaya tidak lazy-load.

Hasil Setelah 7 Hari

Pengukuran RUM lewat CrUX:

MetrikSebelumSesudahCatatan
CLS p75 mobile0,280,04Masuk kategori "baik"
CLS p75 desktop0,110,02Sudah baik, lebih baik lagi
LCP p75 mobile2,8 detik2,1 detikBonus: priority image bantu LCP
Scroll depth p5038%52%Layout stabil meningkatkan engagement

Dampak SEO mulai terlihat di hari ke-14: ranking 6 keyword utama kategori parfum naik rata-rata 4 posisi di Search Console. Saya catatkan ini sebagai korelasi, bukan klaim kausal absolut, karena Google rolling update biasa terjadi paralel.

Pertanyaan Umum

Kenapa width-height saja tidak cukup?

Atribut width dan height di tag image hanya bekerja saat tidak ada CSS yang override ke width: auto. Banyak setup CSS modern (termasuk Tailwind default) membuat gambar width: 100%; height: auto, yang mengabaikan aspect ratio HTML. Solusi pasti: wrapper dengan aspect-ratio CSS.

Kenapa pakai min-h bukan h fixed?

Tinggi card bervariasi karena nama produk bisa 1 atau 2 baris. h fixed bisa potong teks. min-h reservasi tinggi minimum, tapi tetap akomodir variasi sambil mencegah collapse.

Bagaimana monitoring CLS setelah deploy?

Pasang Web Vitals reporter via next/web-vitals dan kirim ke analytics. Cek field data Search Console setiap minggu di awal. Pengukuran lab Lighthouse berguna untuk regresi, tapi field data CrUX yang dipakai Google untuk ranking signal.

Aplikasikan ke Project Anda

Pola yang sama bekerja untuk product listing, blog grid, dan dashboard card. Kuncinya satu: setiap konten yang load asynchronous (gambar, embed, ad slot) harus punya reservasi dimensi di CSS, bukan menunggu konten tiba untuk menentukan tinggi. Audit halaman katalog Anda hari ini: scroll perlahan dengan throttle 4G di DevTools dan lihat apakah ada elemen yang "loncat".

Bagikan

Artikel Terkait

#cls#core-web-vitals#nalesha#grid-layout#website-performance

Butuh website yang benar-benar bekerja?

Hubungi Vito untuk konsultasi gratis 15 menit.

WhatsApp Sekarang