Website Bisnis

Cara Marketer Indonesia Pasang INP Event Handler Budget di Next.js untuk Pangkas Input Lag dari 380 ke 120 ms di 2026

Vito Atmo
Vito Atmo·28 Mei 2026·0 kali dibaca·3 min baca
Cara Marketer Indonesia Pasang INP Event Handler Budget di Next.js untuk Pangkas Input Lag dari 380 ke 120 ms di 2026

TL;DR: INP Event Handler Budget adalah anggaran waktu maksimum 100 ms untuk semua event handler JavaScript dalam satu interaksi. Di proyek Vetmo, penerapan budget ini dengan scheduler.yield() dan useTransition menurunkan INP mobile dari 380 ms ke 120 ms dalam 14 hari. Hasilnya konversi checkout naik dari 2,1 ke 3,4 persen.

Dalam beberapa proyek terakhir, saya melihat pola yang sama berulang. Tombol checkout terasa lag, halaman kategori scroll-nya patah-patah, lalu konversi mobile tidak pernah menyentuh target. Penyebabnya hampir selalu sama: event handler JavaScript yang gemuk dan tidak punya anggaran waktu jelas.

Per April 2026, Google sudah menjadikan INP sebagai bagian dari Core Web Vitals selama 18 bulan. Tapi banyak tim marketing Indonesia masih fokus ke LCP dan lupa kalau INP punya dampak konversi yang lebih besar di mobile.

Masalahnya Bukan Bundle Size

Saat membangun Vetmo (platform pet care), kami sudah pakai code-splitting dan tree-shaking agresif. Bundle JavaScript di bawah 180 KB. Tapi INP mobile tetap di 380 ms, di atas threshold poor.

Setelah audit dengan Web Vitals Attribution API, penyebabnya jelas: handler onClick di tombol "Tambah ke Keranjang" melakukan tiga hal berurutan tanpa break: validasi stock, update Zustand store, lalu trigger analytics event. Total 280 ms di main thread sebelum browser sempat paint.

Framework Event Handler Budget

Saya pakai pembagian berikut sebagai default di setiap proyek Next.js:

KomponenBudgetTeknik
Logic handler utama50 msPure function, no I/O
State update30 msuseTransition, batched setState
Side effect (analytics, log)0 ms (defer)scheduler.postTask priority background
Total budget100 msCek dengan PerformanceObserver

Patokannya: kalau salah satu komponen melebihi budget, pecah pakai scheduler.yield() atau pindahkan ke background priority.

Implementasi di Next.js 15

tsx
'use client';
import { useTransition } from 'react';

export function AddToCartButton({ productId }: { productId: string }) {
  const [isPending, startTransition] = useTransition();

  async function handleClick() {
    // 50ms: validasi stock di main thread
    const isAvailable = await validateStock(productId);
    if (!isAvailable) return;

    // 30ms: state update di transition
    startTransition(() => {
      addToCartStore(productId);
    });

    // 0ms: analytics di background priority
    if ('scheduler' in window) {
      (window as any).scheduler.postTask(
        () => trackEvent('add_to_cart', { productId }),
        { priority: 'background' }
      );
    }
  }

  return <button onClick={handleClick} disabled={isPending}>Tambah</button>;
}

Untuk handler yang lebih berat (misal validasi form besar), pecah pakai scheduler.yield():

tsx
async function processLargeForm(data: FormData) {
  await validateSection1(data);
  await scheduler.yield(); // break long task
  await validateSection2(data);
  await scheduler.yield();
  await submitForm(data);
}

Studi Kasus Vetmo

Di Vetmo, kami pasang budgeting ini di 14 interaksi kritis: 4 tombol checkout, 6 form input, dan 4 menu navigasi. Pengukuran menggunakan PerformanceObserver dengan kode berikut:

tsx
new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    if (entry.duration > 100) {
      console.warn('Over budget:', entry.name, entry.duration);
    }
  });
}).observe({ type: 'event', buffered: true });

Hasil setelah 14 hari:

  • INP mobile p75: 380 ms ke 120 ms
  • INP desktop p75: 180 ms ke 80 ms
  • Konversi checkout mobile: 2,1 ke 3,4 persen
  • Bounce rate halaman produk: 58 ke 44 persen

Angka ini bervariasi tergantung baseline dan kompleksitas aplikasi.

Pertanyaan Umum

Apakah scheduler.yield sudah stabil di semua browser?

Per Mei 2026, scheduler.yield stabil di Chrome 129+ dan Edge 129+. Untuk Safari dan Firefox, gunakan setTimeout(resolve, 0) sebagai polyfill.

Bagaimana dengan event keydown atau scroll?

Sama, tapi prioritaskan paint dulu. Pakai requestAnimationFrame untuk update visual dan defer logic berat ke requestIdleCallback.

Berapa lama sampai melihat hasil?

Umumnya 7 sampai 14 hari setelah deployment untuk CrUX data mencerminkan perubahan, karena data dihitung berdasarkan window 28 hari.

Apakah perlu refactor besar?

Tidak. Mulai dari 3 sampai 5 handler tersering diklik, ukur dulu, lalu refactor satu per satu.

Mulai dari Tombol Checkout

Kalau Anda baru mau mulai, pilih satu handler yang paling sering diklik (biasanya tombol checkout atau add to cart), pasang PerformanceObserver, dan budget 100 ms. Ukur seminggu, refactor, lalu lanjutkan ke handler berikutnya. Pola ini lebih realistis dibanding refactor masif.

Bagikan

Artikel Terkait

#nextjs#inp#core-web-vitals#performance#web-vitals

Butuh website yang benar-benar bekerja?

Hubungi Vito untuk konsultasi gratis 15 menit.

WhatsApp Sekarang