INP (Interaction to Next Paint) adalah metrik Core Web Vitals yang mengukur responsivitas interaksi dan kini penting untuk peringkat serta UX (user experience). Artikel ini menjelaskan cara mengukur, mendiagnosis, serta menurunkan INP pada aplikasi React dengan teknik praktis, alat, dan strategi arsitektur modern.
Dasar Core Web Vitals dan Konsep Responsiveness
Core Web Vitals adalah kumpulan metrik pengalaman pengguna yang fokus pada loading, interaktivitas, dan stabilitas visual; tiga indikator utamanya adalah LCP (Largest Contentful Paint), CLS (Cumulative Layout Shift), dan INP (Interaction to Next Paint).

Ideas Fresh Brainstorming Creative Strategy Concept
Memahami keterkaitan mereka penting karena perbaikan pada satu area sering memengaruhi area lain—misalnya optimasi resource untuk LCP bisa mengubah pola interaksi yang memengaruhi INP.
💻 Mulai Belajar Pemrograman
Belajar pemrograman di Dicoding Academy dan mulai perjalanan Anda sebagai developer profesional.
Daftar SekarangApa itu responsiveness? Bukan sekadar cepat memuat, melainkan seberapa cepat antarmuka merespons input pengguna selama sesi interaksi. Bayangkan menu yang muncul cepat, tetapi tombolnya masih sibuk memproses tugas berat; loading sudah selesai, tetapi pengalaman terasa lambat.
First Input Delay mengukur penundaan pada input pertama saja, sedangkan Interaction to Next Paint mencatat durasi penuh dari banyak interaksi sampai browser menampilkan perubahan visual berikutnya. Dengan kata lain, INP merefleksikan kualitas interaktivitas sepanjang waktu, bukan hanya momen awal.
Contoh nyata masalah INP tinggi: formulir yang terasa lag saat mengetik, tombol klik yang butuh jeda sebelum memberi umpan balik, atau menu dropdown yang tersendat karena long tasks. Target INP ideal adalah dua ratus milidetik (200 ms) atau lebih rendah untuk kategori Good; antara dua ratus hingga lima ratus milidetik (200–500 ms) perlu perbaikan; lebih dari lima ratus milidetik (> 500 ms) dianggap Poor, yang berdampak negatif pada UX dan potensi peringkat SEO.
Selanjutnya kita akan membahas alasan INP menggantikan FID dan cara ini mengubah pendekatan optimasi interaksi pengguna.
Mengapa INP Menggantikan FID dan Dampaknya pada UX
Peralihan dari FID ke INP muncul karena FID hanya menangkap keterlambatan pada interaksi pertama; akibatnya banyak masalah responsivitas yang terjadi kemudian tidak terdeteksi. INP mengukur latensi seluruh interaksi penting dalam halaman dengan fokus pada waktu dari input sampai next paint sehingga mencerminkan pengalaman nyata pengguna sepanjang sesi, bukan hanya detik pertama.
Untuk developer React, implikasinya jelas: optimasi tidak boleh berhenti setelah interaksi awal cepat. Perbaikan harus menyasar distribusi interaksi—memecah long tasks, men-defer pekerjaan non-urgent, memindahkan komputasi ke web worker, dan memperbaiki event handlers yang sinkron berat.
Bayangkan SPA dengan filter daftar yang sering dipakai; FID mungkin baik karena halaman merespons awal, tetapi jika setiap filter menyebabkan frame drop maka INP akan jelek. Fokusmu harus pada konsistensi interaksi berulang, bukan sekadar interaksi pertama.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function onSearch(e) { const q = e.target.value; // prioritaskan responsiveness dengan startTransition startTransition(() => { // operasi render besar di-defer setQuery(q); }); // pekerjaan berat bukan-kritis ke requestIdleCallback if ('requestIdleCallback' in window) { requestIdleCallback(() => heavyIndexing(q)); } else { setTimeout(() => heavyIndexing(q), 200); } } |
Alat dan Metode Mengukur Performa di Aplikasi React
Gunakan kombinasi Lighthouse, PageSpeed Insights, Chrome DevTools Performance, web-vitals dan solusi RUM untuk mendapatkan gambaran lab dan field terkait INP.
Lighthouse memberi estimasi lab, sedangkan PageSpeed Insights dan RUM menunjukkan perilaku nyata pengguna. Untuk lab, rekam skenario interaksi yang representatif; untuk field, kumpulkan metrik pada klien dan hitung persentil ke-98 agar fokus pada pengalaman terburuk yang dirasakan pengguna.
Pada Chrome DevTools Performance, aktifkan perekaman, lakukan interaksi nyata, lalu berhenti dan filter untuk Long Tasks—task lebih dari lima puluh milidetik biasanya menandai blocking.
Aktifkan juga kategori Event Timing dan cari event dengan durasi tinggi untuk mengidentifikasi event handlers berat atau re-render besar yang memblokir Interaction to Next Paint.
Untuk pengumpulan dalam produksi, pakai web-vitals dan kirim hasil ke sistem monitoring. Contoh pengiriman sederhananya berikut.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import { getINP } from 'web-vitals'; getINP(metric => { fetch('/collect-metric', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: metric.name, value: metric.value, entries: metric.entries }) }); }); |
Lengkapi diagnosis dengan checklist metrik: Total Blocking Time, jumlah Long Tasks, FPS drop, dan memory spikes; gunakan OpenTelemetry atau platform RUM untuk korelasi stack traces dan release tags. Langkah berikutnya adalah memprofil event loop dan main thread untuk menemukan kode yang menyebabkan long tasks dan menuntun optimasi lebih lanjut.
Profiling Interaksi Analisa Event Loop dan Main Thread
Mulai dengan merekam performance trace pada Chrome DevTools lalu aktifkan pelacakan interaksi; fokus pada long tasks (lebih dari lima puluh ms) dan kolom Event Handler untuk melihat fungsi mana yang memblokir Main Thread.
Gunakan panel Summary dan Bottom-Up untuk menyorot durasi kumulatif, serta filter ke interaksi klik atau keyboard agar relevan dengan INP.
Identifikasi sumber seperti scripting, rendering, layout, dan painting, lalu segmentasi berdasarkan file/module lewat stack trace dan sumber sumber peta (source maps). Cari pola umum: third-party scripts, serial setState, loop sinkron besar, parsing masif, dan reflow akibat pembacaan DOM sinkron.
Untuk mitigasi, defer kode non-kritis, split tasks menjadi potongan kecil, gunakan requestIdleCallback atau setTimeout untuk chunking, dan pindahkan parsing atau komputasi berat ke Web Worker. Debounce atau throttle event handlers serta lazy-load paket pihak ketiga sehingga interaksi tidak terblokir.
Contoh singkat: temukan handler X yang membuat long task, catat INP awal, refactor dengan chunking, ukur ulang. Kode berikut memperlihatkan teknik chunking sederhana sebelum memindahkannya ke worker.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// sebelum: loop sinkron menggantung UI function handleClick(items) { for (let i = 0; i < items.length; i++) { processItem(items[i]); } } // sesudah: chunking dengan setTimeout function handleClick(items) { let i = 0; function chunk() { const end = Math.min(i + 50, items.length); for (; i < end; i++) processItem(items[i]); if (i < items.length) setTimeout(chunk, 0); } chunk(); } |
Strategi Kode React untuk Menurunkan Latensi Interaksi
Dari profiling yang sudah kamu lakukan, fokus yang paling efektif adalah memecah long tasks pada main thread. Hindari pekerjaan berat langsung dalam event handlers; pindahkan komputasi ke web worker atau jalankan secara async sehingga input tidak terblokir. Analogi singkat: lebih baik menugaskan kurir untuk mengantar paket besar daripada menunggu di antrean kasir.
Pada React 18 manfaatkan useTransition atau startTransition untuk menunda update berprioritas rendah sehingga render mahal tidak mencuri waktu responsif. Contoh kode singkat ada di bawah untuk pola umum penggunaan dan offload pada worker.
Gunakan useMemo, useCallback, dan React.memo agar komponen tidak re-render tanpa perlu, tetapi lakukan hanya bila ada cost nyata. Terapkan code-splitting dan lazy loading dengan React.lazy dan Suspense serta pilih local state untuk state transient dan global state bila memang diperlukan.
Andalkan automatic batching dan functional updates untuk menghindari rantai update sinkron. Untuk third-party scripts, pakai lazy-init, muat secara async, atau sandarkan pada iframe agar tidak mengganggu INP. Tetapkan metrik INP dan trace sebelum deploy supaya pipeline monitoring selanjutnya dapat menangkap regresi.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// useTransition example const [isPending, startTransition] = useTransition(); function onSearch(q) { setQuery(q); startTransition(() => { fetchResults(q).then(setResults); }); } // web worker offload const worker = new Worker(new URL('./worker.js', import.meta.url)); worker.postMessage(data); worker.onmessage = (e) => setResult(e.data); |
Praktik Deploy Monitoring dan Regression Testing untuk Responsiveness
Instrumentasi RUM harus mengirim metrik INP lengkap dengan konteks page, negara, dan cohort pengguna (mis. role, plan, device). Pasang web-vitals dalam entry bundle untuk mengukur INP, lalu kirim event ke pipeline observability (adatnya ke Datadog, Sentry, atau ke BigQuery) dengan tag geolocation dan cohort untuk agregasi.
Tetapkan threshold berdasarkan pedoman Core Web Vitals (Good ≤ dua ratus ms, Needs-improvement dua ratus–lima ratus ms, Poor > lima ratus ms) dan buat alert pada persentil tujuh puluh lima per page/cohort. Runbook singkat: triage → capture trace/long task → deploy canary/flag rollback → postmortem; sertakan langkah mitigasi cepat, seperti men-disable fitur non-kritis.
Masukkan synthetic test ke CI (GitHub Actions/GitLab) yang menjalankan interaksi otomatis untuk mengukur INP pada tiap build; bandingkan median terhadap baseline dan blok PR bila regresi melebihi delta yang disepakati. Contoh sederhana Playwright untuk menangkap INP berada di bawah.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const { chromium } = require('playwright'); const fs = require('fs'); (async ()=> { const browser = await chromium.launch(); const page = await browser.newPage(); await page.goto(process.argv[2] || 'https://example.com', {waitUntil:'load'}); await page.addScriptTag({path: require.resolve('web-vitals/dist/web-vitals.iife.js')}); const inp = await page.evaluate(() => new Promise(resolve => { webVitals.getINP(metric => resolve(metric.value)); })); console.log('INP', inp); fs.writeFileSync('inp.json', JSON.stringify({inp})); await browser.close(); })(); |
Untuk rollout, gunakan canary release plus feature flag (mis. LaunchDarkly/Split) sehingga kamu bisa memantau INP secara bertahap dan menghentikan release otomatis bila metrik memburuk.
Penutup
Setelah mengikuti panduan ini, kamu dapat memahami cara mengukur INP, mengenali penyebab utama, dan menerapkan perubahan kode serta arsitektur React yang efektif. Kamu juga bisa fokus pada pemecahan long tasks, optimasi event handlers, dan monitoring berkelanjutan akan menurunkan INP serta meningkatkan pengalaman pengguna.