Menilai performa pemuatan di lapangan dengan Waktu Navigasi dan Waktu Sumber Daya

Pelajari dasar-dasar penggunaan API Navigation dan Resource Timing untuk menilai performa pemuatan di kolom.

Jika Anda telah menggunakan throttling koneksi di panel jaringan pada alat developer browser (atau Lighthouse di Chrome) untuk menilai performa pemuatan, Anda tahu seberapa praktis alat tersebut untuk penyesuaian performa. Anda dapat mengukur dampak pengoptimalan performa dengan cepat dengan kecepatan koneksi dasar pengukuran yang konsisten dan stabil. Satu-satunya masalah adalah bahwa ini adalah pengujian sintetis, yang menghasilkan data lab, bukan data kolom.

Pengujian sintetis tidak berarti buruk, tetapi tidak merepresentasikan seberapa cepat situs Anda dimuat untuk pengguna sungguhan. Cara ini memerlukan data kolom, yang dapat Anda kumpulkan dari Navigation Timing API dan Resource Timing API.

API untuk membantu Anda menilai performa pemuatan di lapangan

Navigation Timing dan Resource Timing adalah dua API serupa dengan tumpang-tindih signifikan yang mengukur dua hal yang berbeda:

  • Waktu Navigasi mengukur kecepatan permintaan untuk dokumen HTML (yaitu, permintaan navigasi).
  • Resource Timing mengukur kecepatan permintaan untuk resource yang bergantung pada dokumen seperti CSS, JavaScript, gambar, dan sebagainya.

API ini mengekspos datanya dalam buffer entri performa, yang dapat diakses di browser dengan JavaScript. Ada beberapa cara untuk mengkueri buffer performa, tetapi cara yang umum adalah dengan menggunakan performance.getEntriesByType:

// Get Navigation Timing entries:
performance.getEntriesByType('navigation');

// Get Resource Timing entries:
performance.getEntriesByType('resource');

performance.getEntriesByType menerima string yang menjelaskan jenis entri yang ingin Anda ambil dari buffer entri performa. 'navigation' dan 'resource' masing-masing mengambil waktu untuk Navigation Timing API dan Resource Timing API.

Jumlah informasi yang diberikan API ini bisa sangat banyak, tetapi merupakan kunci untuk mengukur performa pemuatan di lapangan, karena Anda dapat mengumpulkan waktu ini dari pengguna saat mereka mengunjungi situs Anda.

Masa pakai dan waktu permintaan jaringan

Mengumpulkan dan menganalisis waktu navigasi dan sumber daya seperti halnya arkeologi, di mana Anda merekonstruksi kehidupan sekilas dari permintaan jaringan setelah kejadian. Terkadang membantu memvisualisasikan konsep, dan jika ada permintaan jaringan yang terkait, alat developer browser Anda dapat membantu.

Diagram pengaturan waktu jaringan seperti yang ditampilkan di Chrome DevTools. Waktu yang ditunjukkan adalah untuk antrean permintaan, negosiasi koneksi, permintaan itu sendiri, dan respons dalam batang berkode warna.
Visualisasi permintaan jaringan di panel jaringan DevTools Chrome

Proses permintaan jaringan memiliki fase yang berbeda, seperti pencarian DNS, pembentukan koneksi, negosiasi TLS, dan seterusnya. Waktu ini direpresentasikan sebagai DOMHighResTimestamp. Bergantung pada browser Anda, perincian pengaturan waktu mungkin berkurang hingga mikrodetik, atau dibulatkan ke milidetik. Mari kita periksa fase-fase ini secara mendetail, dan bagaimana fase tersebut berhubungan dengan Waktu Navigasi dan Pengaturan Waktu Resource.

pencarian DNS

Saat pengguna membuka URL, Domain Name System (DNS) akan dikueri untuk menerjemahkan domain ke alamat IP. Proses ini mungkin memakan waktu yang cukup lama—bahkan waktu yang perlu Anda ukur di lapangan. Navigation Timing dan Resource Timing mengekspos dua pengaturan waktu terkait DNS:

  • domainLookupStart adalah saat pencarian DNS dimulai.
  • domainLookupEnd adalah saat pencarian DNS berakhir.

Menghitung total waktu pencarian DNS dapat dilakukan dengan mengurangi metrik awal dari metrik akhir:

// Measuring DNS lookup time
const [pageNav] = performance.getEntriesByType('navigation');
const totalLookupTime = pageNav.domainLookupEnd - pageNav.domainLookupStart;

Negosiasi koneksi

Faktor lain yang berkontribusi terhadap performa pemuatan adalah negosiasi koneksi, yaitu latensi yang terjadi saat terhubung ke server web. Jika HTTPS terlibat, proses ini juga akan menyertakan waktu negosiasi TLS. Fase koneksi terdiri dari tiga pengaturan waktu:

  • connectStart adalah saat browser mulai membuka koneksi ke server web.
  • secureConnectionStart menandai saat klien memulai negosiasi TLS.
  • connectEnd adalah saat koneksi ke server web telah dibuat.

Mengukur total waktu koneksi mirip dengan mengukur total waktu pencarian DNS: Anda mengurangi waktu mulai dari waktu akhir. Namun, ada properti secureConnectionStart tambahan yang dapat berupa 0 jika HTTPS tidak digunakan atau jika koneksinya persisten. Jika ingin mengukur waktu negosiasi TLS, Anda perlu mengingatnya:

// Quantifying total connection time
const [pageNav] = performance.getEntriesByType('navigation');
const connectionTime = pageNav.connectEnd - pageNav.connectStart;
let tlsTime = 0; // <-- Assume 0 to start with

// Was there TLS negotiation?
if (pageNav.secureConnectionStart > 0) {
  // Awesome! Calculate it!
  tlsTime = pageNav.connectEnd - pageNav.secureConnectionStart;
}

Setelah pencarian DNS dan negosiasi koneksi berakhir, pengaturan waktu yang terkait dengan pengambilan dokumen dan resource dependennya akan ikut berperan.

Permintaan dan respons

Performa pemuatan dipengaruhi oleh dua jenis faktor:

  • Faktor ekstrinsik: Faktor-faktor ini meliputi latensi dan bandwidth. Selain memilih perusahaan hosting dan CDN, mereka (sebagian besar) berada di luar kendali kami, karena pengguna dapat mengakses web dari mana saja.
  • Faktor intrinsik: Hal-hal seperti arsitektur sisi klien dan server, serta ukuran resource dan kemampuan kami untuk mengoptimalkan hal-hal tersebut, berada dalam kendali kami.

Kedua jenis faktor tersebut memengaruhi performa pemuatan. Waktu yang terkait dengan faktor-faktor ini sangat penting, karena menjelaskan berapa lama sumber daya yang diperlukan untuk mengunduh. Navigation Timing dan Resource Timing menjelaskan performa pemuatan dengan metrik berikut:

  • fetchStart menandai saat browser mulai mengambil resource (Resource Timing) atau dokumen untuk permintaan navigasi (Navigation Timing). Hal ini mendahului permintaan yang sebenarnya, dan merupakan titik saat browser memeriksa cache (misalnya, instance HTTP dan Cache).
  • workerStart menandai saat permintaan mulai ditangani dalam pengendali peristiwa fetch pekerja layanan. Ini akan menjadi 0 saat tidak ada pekerja layanan yang mengontrol halaman saat ini.
  • requestStart adalah saat browser membuat permintaan.
  • responseStart adalah saat byte pertama respons tiba.
  • responseEnd adalah saat byte terakhir respons tiba.

Waktu ini memungkinkan Anda mengukur beberapa aspek performa pemuatan, seperti pencarian cache dalam pekerja layanan dan waktu download:

// Cache seek plus response time of the current document
const [pageNav] = performance.getEntriesByType('navigation');
const fetchTime = pageNav.responseEnd - pageNav.fetchStart;

// Service worker time plus response time
let workerTime = 0;

if (pageNav.workerStart > 0) {
  workerTime = pageNav.responseEnd - pageNav.workerStart;
}

Anda juga dapat mengukur aspek lain dari latensi permintaan/respons:

const [pageNav] = performance.getEntriesByType('navigation');

// Request time only (excluding redirects, DNS, and connection/TLS time)
const requestTime = pageNav.responseStart - pageNav.requestStart;

// Response time only (download)
const responseTime = pageNav.responseEnd - pageNav.responseStart;

// Request + response time
const requestResponseTime = pageNav.responseEnd - pageNav.requestStart;

Pengukuran lain yang dapat Anda buat

Navigation Timing dan Resource Timing berguna untuk lebih dari apa yang contoh di atas garis besar. Berikut beberapa situasi lain terkait pengaturan waktu relevan yang mungkin layak untuk dipelajari:

  • Pengalihan halaman: Pengalihan merupakan sumber latensi tambahan yang diabaikan, terutama rantai pengalihan. Latensi ditambahkan dengan beberapa cara, seperti hop HTTP-ke-HTTPs, serta pengalihan 302/yang tidak di-cache. Pengaturan waktu redirectStart, redirectEnd, dan redirectCount berguna dalam menilai latensi pengalihan.
  • Penghapusan muatan dokumen: Di halaman yang menjalankan kode di pengendali peristiwa unload, browser harus mengeksekusi kode tersebut sebelum dapat membuka halaman berikutnya. unloadEventStart dan unloadEventEnd mengukur penghapusan muatan dokumen.
  • Pemrosesan dokumen: Waktu pemrosesan dokumen mungkin tidak penting kecuali jika situs Anda mengirimkan payload HTML yang sangat besar. Jika ini menggambarkan situasi Anda, pengaturan waktu domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd, dan domComplete mungkin menarik.

Memperoleh pengaturan waktu dalam kode aplikasi

Semua contoh yang ditampilkan sejauh ini menggunakan performance.getEntriesByType, tetapi ada cara lain untuk membuat kueri buffer entri performa, seperti performance.getEntriesByName dan performance.getEntries. Metode ini tidak masalah jika hanya analisis ringan yang diperlukan. Namun, dalam situasi lain, holder tersebut dapat menyebabkan pekerjaan thread utama yang berlebihan dengan melakukan iterasi pada sejumlah besar entri, atau bahkan berulang kali melakukan polling buffer performa untuk menemukan entri baru.

Pendekatan yang direkomendasikan untuk mengumpulkan entri dari buffer entri performa adalah menggunakan PerformanceObserver. PerformanceObserver memproses entri performa, dan menyediakannya saat ditambahkan ke buffer:

// Create the performance observer:
const perfObserver = new PerformanceObserver((observedEntries) => {
  // Get all resource entries collected so far:
  const entries = observedEntries.getEntries();

  // Iterate over entries:
  for (let i = 0; i < entries.length; i++) {
    // Do the work!
  }
});

// Run the observer for Navigation Timing entries:
perfObserver.observe({
  type: 'navigation',
  buffered: true
});

// Run the observer for Resource Timing entries:
perfObserver.observe({
  type: 'resource',
  buffered: true
});

Metode pengumpulan waktu ini mungkin terasa canggung jika dibandingkan dengan mengakses langsung buffer entri performa, tetapi lebih baik mengaitkan thread utama dengan pekerjaan yang tidak melayani tujuan penting dan berhubungan langsung dengan pengguna.

Rumah Phoning

Setelah Anda mengumpulkan semua pengaturan waktu yang dibutuhkan, Anda dapat mengirimkannya ke endpoint untuk analisis lebih lanjut. Dua cara untuk melakukannya adalah dengan navigator.sendBeacon atau fetch dengan opsi keepalive yang ditetapkan. Kedua metode tersebut akan mengirim permintaan ke endpoint yang ditentukan dengan cara yang tidak memblokir, dan permintaan akan diantrekan dengan cara yang aktif lebih lama dibandingkan sesi halaman saat ini, jika diperlukan:

// Caution: If you have lots of performance entries, don't
// do this. This is an example for illustrative purposes.
const data = JSON.stringify(performance.getEntries()));

// The endpoint to transmit the encoded data to
const endpoint = '/analytics';

// Check for fetch keepalive support
if ('keepalive' in Request.prototype) {
  fetch(endpoint, {
    method: 'POST',
    body: data,
    keepalive: true,
    headers: {
      'Content-Type': 'application/json'
    }
  });
} else if ('sendBeacon' in navigator) {
  // Use sendBeacon as a fallback
  navigator.sendBeacon(endpoint, data);
}

Dalam contoh ini, string JSON akan tiba dalam payload POST yang dapat Anda dekode dan proses/simpan di backend aplikasi sesuai kebutuhan.

Menyelesaikan

Setelah metrik dikumpulkan, terserah Anda untuk mencari tahu cara menganalisis data {i>field<i} tersebut. Saat menganalisis data {i>field<i}, ada beberapa aturan umum yang harus diikuti untuk memastikan Anda menarik kesimpulan yang tepat:

  • Hindari nilai rata-rata, karena data tersebut tidak mewakili pengalaman pengguna mana pun, dan mungkin menyimpang dari pencilan.
  • Mengandalkan persentil. Dalam set data metrik performa berbasis waktu, lebih rendah lebih baik. Ini berarti bahwa ketika Anda memprioritaskan persentil rendah, Anda hanya memperhatikan pengalaman tercepat.
  • Prioritaskan longtail nilai. Saat memprioritaskan pengalaman pada persentil ke-75 atau lebih tinggi, Anda menempatkan fokus pada kemampuannya: pada pengalaman paling lambat.

Panduan ini tidak dimaksudkan sebagai referensi lengkap tentang Navigasi atau Resource Timing, tetapi sebuah titik awal. Berikut beberapa referensi tambahan yang mungkin berguna bagi Anda:

Dengan API ini dan data yang disediakannya, Anda akan lebih siap untuk memahami bagaimana performa pemuatan dialami oleh pengguna nyata, yang akan memberi Anda kepercayaan diri yang lebih besar dalam mendiagnosis dan mengatasi masalah performa pemuatan di lapangan.