Mengukur Performance — Performance

Mengukur Web Performance Sebelum mengoptimasi, kita harus bisa mengukur. "You can't improve what you don't measure." Performance API Browser menyediakan…

Mengukur performance artinya mengambil angka nyata: berapa milidetik yang dibutuhkan halaman, file mana yang paling lambat, berapa kilobyte yang di-download. Tanpa angka, "kayaknya sudah cepat" cuma perasaan. Mirip timbangan badan: kalau diet tanpa pernah menimbang, kamu gak tahu usahamu berhasil atau gak.

🧪 Tebakan cepat: Lighthouse di laptopmu bilang LCP 1,2 detik, tapi data pengguna nyata bilang LCP 3,8 detik. Mana yang salah? Jawabannya ada di bagian "Lab data dan field data".

Lab data dan field data

Itu jawaban tebakannya: gak ada yang salah. Laptopmu kencang, sedangkan banyak penggunamu memakai HP yang lebih lambat. Untuk menilai pengalaman pengguna, field data yang jadi patokan. Lab data dipakai untuk mencari penyebabnya. Satu lagi: INP butuh klik sungguhan, jadi Lighthouse gak bisa mengukurnya. Lighthouse menampilkan TBT (Total Blocking Time) sebagai gantinya.

Mengukur kodemu sendiri

Browser punya objek performance. Dengan mark dan measure, kamu bisa mengukur berapa lama sepotong kode berjalan:

performance.mark("sort-mulai");
angka.sort((a, b) => a - b); // kode yang mau diukur
performance.mark("sort-selesai");
performance.measure("sort", "sort-mulai", "sort-selesai");

const [hasil] = performance.getEntriesByName("sort");
console.log(hasil.duration); // misalnya 23.4 (milidetik)

Resource Timing: tiap file yang di-download

performance.getEntriesByType("resource") memberi satu entry untuk tiap file yang di-download halaman: CSS, JavaScript, gambar, font. Tiga isinya yang paling berguna:

const data = performance.getEntriesByType("resource").map((e) => ({
  name: e.name,
  duration: e.duration,
  transferSize: e.transferSize,
}));

Meringkas angkanya

Entry yang banyak lebih enak dibaca kalau diringkas. Pakai tiga entry ini (juga dipakai di Lab dan latihan):

function analyzeTimings(timings) {
  let totalDuration = 0;
  let totalBytes = 0;
  let slowest = timings[0];

  for (const t of timings) {
    totalDuration += t.duration;
    totalBytes += t.transferSize;
    if (t.duration > slowest.duration) slowest = t;
  }

  return {
    totalDuration,
    slowestResource: slowest.name,
    totalTransferKB: Math.floor(totalBytes / 1024),
    count: timings.length,
  };
}

const data = [
  { name: "style.css", duration: 120, transferSize: 15360 },
  { name: "app.js", duration: 340, transferSize: 102400 },
  { name: "logo.png", duration: 80, transferSize: 5120 },
];
console.log(analyzeTimings(data));
// { totalDuration: 540, slowestResource: "app.js", totalTransferKB: 120, count: 3 }
Putaran t.name totalDuration totalBytes slowest
1 style.css 120 15.360 style.css
2 app.js 460 117.760 app.js
3 logo.png 540 122.880 app.js

💡 Core Web Vitals dari pengguna nyata

Library web-vitals (buatan tim Chrome) mengukur LCP, INP, dan CLS di browser pengunjungmu:

import { onLCP, onINP, onCLS } from "web-vitals";

function laporkan(metric) {
  console.log(metric.name, metric.value, metric.rating); // misalnya "LCP" 2180 "good"
}

onLCP(laporkan);
onINP(laporkan);
onCLS(laporkan);

metric.rating berisi "good", "needs-improvement", atau "poor". Di aplikasi sungguhan, ganti console.log dengan navigator.sendBeacon(...) untuk mengirimnya ke server analytics-mu. Di balik layar, library ini memakai PerformanceObserver, yang memberi tahu tiap ada entry baru:

new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log("kandidat LCP:", entry.startTime, entry.element);
  }
}).observe({ type: "largest-contentful-paint", buffered: true });

⚠️ Jebakan yang sering ketemu

TL;DR: Lab data (Lighthouse) diukur di simulasi terkontrol dan bagus untuk mencari penyebab. Field data (CrUX, web-vitals) datang dari pengguna nyata dan jadi patokan pengalaman mereka. Ukur kodemu dengan performance.mark dan performance.measure, dan baca tiap file lewat performance.getEntriesByType("resource") (name, duration, transferSize). Untuk meringkasnya: jumlahkan durasi, cari durasi terbesar, jumlahkan byte lalu bagi 1024 dengan Math.floor, dan hitung banyaknya entry, dengan key berurutan totalDuration, slowestResource, totalTransferKB, count.

Yang akan kamu pelajari