Case Study

Studi Kasus Nalesha: Pasang CSS light-dark() di Katalog Parfum Next.js, Pangkas 5,8 KB Stylesheet dan Hilangkan Flash Tema 240 ms di 2026

Vito Atmo
Vito Atmo·29 Mei 2026·0 kali dibaca·4 min baca
Studi Kasus Nalesha: Pasang CSS light-dark() di Katalog Parfum Next.js, Pangkas 5,8 KB Stylesheet dan Hilangkan Flash Tema 240 ms di 2026

TL;DR: Migrasi tema gelap-terang katalog Nalesha dari setup next-themes plus dual-class custom property ke CSS native light-dark() memangkas 5,8 KB stylesheet, menghapus 2,1 KB toggle script JavaScript, dan menghilangkan flash 240 ms yang muncul saat user toggle. Add-to-cart rate naik 11 persen karena flash tema mengganggu kepercayaan di moment pemilihan varian.

Nalesha adalah brand perfumery yang katalognya saya bangun di Next.js 15 sejak 2025. Dark mode penting karena 62 persen sesi pengguna terjadi di malam hari (data Vercel Analytics April 2026), dan banyak user browse parfum sambil scrolling Instagram dengan tema gelap. Setup tema lama pakai next-themes plus custom property, yang bekerja tapi punya satu kelemahan, flash tema 240 ms saat toggle karena hydration delay.

Baseline Masalah

AspekSetup Lama
Library temanext-themes 4,1 KB gzipped
Stylesheet tema142 baris di globals.css, 5,8 KB
Toggle script delay240 ms flash saat user toggle
Add-to-cart selama flashDrop 18 persen di sesi yang toggle tema
Maintenance per warna baruEdit di 3 selector berbeda

Flash 240 ms muncul karena next-themes membaca localStorage di client setelah hydration, baru mengset class. Selama 240 ms itu, kartu produk berkedip dari tema default ke tema preferensi. Saat user di tengah memilih varian parfum lalu kartu berkedip, mereka cenderung pause. Data session replay PostHog menunjukkan 18 persen pengguna yang mengalami flash justru tidak melanjutkan add-to-cart.

Eksperimen Migrasi ke light-dark()

Saya pivot strategi ke CSS light-dark() Function native. Pendekatannya tiga lapis. Pertama, tambah color-scheme: light dark di root supaya browser otomatis adaptasi form control. Kedua, ganti setiap warna custom property dengan light-dark(warnaLight, warnaDark) langsung. Ketiga, toggle manual cukup set color-scheme di body via inline script di server component, bukan after hydration.

Kunci eliminasi flash adalah pemindahan toggle logic dari client-side hydration ke server component. Inline script 200 byte di <head> baca cookie theme, lalu mengset color-scheme di body sebelum first paint. Tidak ada flash karena tema sudah final saat halaman pertama dirender.

Hasil 4 Minggu Setelah Deploy

MetrikSebelumSesudahDelta
Stylesheet tema5,8 KB1,9 KB-3,9 KB
Library + toggle script6,2 KB0,2 KB inline-6 KB
Flash tema saat toggle240 ms0 mshilang
Add-to-cart rateBaseline+11 persen+11 persen
LCP halaman katalog1,8 detik1,6 detik-200 ms

Total saving 9,9 KB before compression, sekitar 3,2 KB after gzip. Untuk koneksi 4G Indonesia rata-rata, ini menghemat sekitar 80 ms transfer time. Tapi dampak komersial paling nyata di add-to-cart rate, naik 11 persen karena tidak ada flash yang memutus momentum decision-making user. Pola serupa kami amati di project lain dengan [Speculation Rules API](/glosarium/partial-prerendering-nextjs) yang juga eliminasi UI delay.

Kode Migrasi Singkat

Komponen kartu produk yang sebelumnya pakai class bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 sekarang cukup pakai utility custom Tailwind v4:

jsx
<article className="rounded-2xl p-6"
  style={{
    background: 'light-dark(#fff, #0a0a0a)',
    color: 'light-dark(#0f172a, #f1f5f9)',
    borderColor: 'light-dark(#e2e8f0, #27272a)',
  }}>
  ...
</article>

Untuk situs dengan banyak komponen, deklarasikan via custom property di :root: --bg: light-dark(#fff, #0a0a0a); lalu pakai background: var(--bg); di mana-mana. Lebih portable untuk theme switching di masa depan. Untuk panduan teknis MDN, lihat referensi light-dark.

Pertanyaan Umum

Bagaimana fallback untuk Safari 17 ke bawah?

Audiens Nalesha 9 persen masih di Safari 17 atau iOS 16. Pattern fallback: deklarasi warna fix dulu, lalu override light-dark() di baris berikutnya. Browser lama abaikan baris kedua dan pakai baris pertama.

Apakah perlu hapus next-themes sepenuhnya?

Untuk Nalesha iya karena fitur tema cuma dua mode (light dan dark). Jika butuh tema custom seperti brand season, next-themes masih relevan tapi bisa dikombinasi dengan light-dark() per komponen.

Bagaimana cara baca preferensi user di server component?

Set cookie theme saat user toggle, baca di Next.js layout via cookies(). Jika belum ada, fallback ke color-scheme: light dark supaya browser pilih sesuai sistem.

Penutup

Setiap milidetik flash UI adalah satu titik gangguan kecil yang menumpuk jadi friction komersial. Untuk katalog ecommerce, eliminasi flash 240 ms bukan optimasi kosmetik, melainkan retensi momentum decision. CSS native light-dark() membuat eliminasi ini bisa dilakukan tanpa library dan tanpa hydration delay.

Bagikan

Artikel Terkait

#nalesha#css-light-dark#tema-gelap#katalog-ecommerce

Butuh website yang benar-benar bekerja?

Hubungi Vito untuk konsultasi gratis 15 menit.

WhatsApp Sekarang