Pengantar Performance API

Diterbitkan: 2022-08-10

Performance API mengukur responsivitas aplikasi web langsung Anda pada perangkat pengguna nyata dan koneksi jaringan. Ini dapat membantu mengidentifikasi kemacetan di sisi klien dan kode sisi server Anda dengan:

  • waktu pengguna: Pengukuran khusus kinerja fungsi JavaScript sisi klien
  • waktu cat: Metrik rendering browser
  • waktu sumber daya: Memuat kinerja aset dan panggilan Ajax
  • waktu navigasi: Metrik pemuatan halaman, termasuk pengalihan, pencarian DNS, kesiapan DOM, dan banyak lagi

API mengatasi beberapa masalah yang terkait dengan penilaian kinerja umum:

  1. Pengembang sering menguji aplikasi pada PC kelas atas yang terhubung ke jaringan cepat. DevTools dapat meniru perangkat yang lebih lambat, tetapi tidak selalu menyoroti masalah dunia nyata ketika sebagian besar klien menjalankan ponsel berusia dua tahun yang terhubung ke WiFi bandara.
  2. Opsi pihak ketiga seperti Google Analytics sering kali diblokir, sehingga menghasilkan hasil dan asumsi yang tidak tepat. Anda juga mungkin mengalami implikasi privasi di beberapa negara.
  3. Performance API dapat secara akurat mengukur berbagai metrik lebih baik daripada metode seperti Date() .

Ingin mempelajari lebih lanjut tentang menggunakan Performance API? Mulai di sini... Klik untuk Tweet
Bagian berikut menjelaskan cara Anda dapat menggunakan Performance API. Beberapa pengetahuan tentang JavaScript dan metrik pemuatan halaman direkomendasikan.

Ketersediaan API Kinerja

Sebagian besar browser modern mendukung Performance API – termasuk IE10 dan IE11 (bahkan IE9 memiliki dukungan terbatas). Anda dapat mendeteksi keberadaan API menggunakan:

 if ('performance' in window) { // use Performance API }

Tidak mungkin untuk sepenuhnya Polyfill API, jadi berhati-hatilah dengan browser yang hilang. Jika 90% pengguna Anda senang menjelajah dengan Internet Explorer 8, Anda hanya akan mengukur 10% klien dengan aplikasi yang lebih mumpuni.

API dapat digunakan di Web Worker, yang menyediakan cara untuk mengeksekusi perhitungan kompleks di thread latar belakang tanpa menghentikan operasi browser.

Sebagian besar metode API dapat digunakan di Node.js sisi server dengan modul perf_hooks standar:

 // Node.js performance import { performance } from 'node:perf_hooks'; // or in Common JS: const { performance } = require('node:perf_hooks'); console.log( performance.now() );

Deno menyediakan Performance API standar:

 // Deno performance console.log( performance.now() );

Anda perlu menjalankan skrip dengan izin --allow-hrtime untuk mengaktifkan pengukuran waktu resolusi tinggi:

 deno run --allow-hrtime index.js

Kinerja sisi server biasanya lebih mudah untuk dinilai dan dikelola karena bergantung pada beban, CPU, RAM, hard disk, dan batas layanan cloud. Upgrade perangkat keras atau opsi manajemen proses seperti PM2, clustering, dan Kubernetes bisa lebih efektif daripada kode refactoring.

Bagian berikut berkonsentrasi pada kinerja sisi klien karena alasan ini.

Pengukuran Kinerja Kustom

Performance API dapat digunakan untuk mengatur waktu kecepatan eksekusi fungsi aplikasi Anda. Anda mungkin pernah menggunakan atau menemukan fungsi pengaturan waktu menggunakan Date() :

 const timeStart = new Date(); runMyCode(); const timeTaken = new Date() - timeStart; console.log(`runMyCode() executed in ${ timeTaken }ms`);

Performance API menawarkan dua manfaat utama:

  1. Akurasi yang lebih baik: Date() mengukur hingga milidetik terdekat, tetapi Performance API dapat mengukur sepersekian milidetik (bergantung pada browser).
  2. Keandalan yang lebih baik: Pengguna atau OS dapat mengubah waktu sistem sehingga metrik berbasis Date() tidak akan selalu akurat. Ini berarti fungsi Anda bisa tampak sangat lambat saat jam bergerak maju!

Setara Date() adalah performance.now() yang mengembalikan stempel waktu resolusi tinggi yang disetel ke nol saat proses yang bertanggung jawab untuk membuat dokumen dimulai (halaman telah dimuat):

 const timeStart = performance.now(); runMyCode(); const timeTaken = performance.now() - timeStart; console.log(`runMyCode() executed in ${ timeTaken }ms`);

Properti performance.timeOrigin non-standar juga dapat mengembalikan stempel waktu mulai 1 Januari 1970 meskipun ini tidak tersedia di IE dan Deno.

performance.now() menjadi tidak praktis saat melakukan lebih dari beberapa pengukuran. Performance API menyediakan buffer tempat Anda dapat merekam peristiwa untuk analisis selanjutnya dengan meneruskan nama label ke performance.mark() :

 performance.mark('start:app'); performance.mark('start:init'); init(); // run initialization functions performance.mark('end:init'); performance.mark('start:funcX'); funcX(); // run another function performance.mark('end:funcX'); performance.mark('end:app');

Array semua objek tanda di buffer Kinerja dapat diekstraksi menggunakan:

 const mark = performance.getEntriesByType('mark');

Contoh hasil:

 [ { detail: null duration: 0 entryType: "mark" name: "start:app" startTime: 1000 }, { detail: null duration: 0 entryType: "mark" name: "start:init" startTime: 1001 }, { detail: null duration: 0 entryType: "mark" name: "end:init" startTime: 1100 }, ... ]

Metode performance.measure() menghitung waktu antara dua tanda dan juga menyimpannya di buffer Performance. Anda memberikan nama ukuran baru, nama tanda awal (atau nol untuk mengukur dari pemuatan halaman), dan nama tanda akhir (atau nol untuk mengukur waktu saat ini):

 performance.measure('init', 'start:init', 'end:init');

Objek PerformanceMeasure ditambahkan ke buffer dengan durasi waktu yang dihitung. Untuk mendapatkan nilai ini, Anda dapat meminta larik semua ukuran:

 const measure = performance.getEntriesByType('measure');

atau meminta ukuran dengan namanya:

 performance.getEntriesByName('init');

Contoh hasil:

 [ { detail: null duration: 99 entryType: "measure" name: "init" startTime: 1001 } ]

Menggunakan Penyangga Kinerja

Selain tanda dan ukuran, Performance buffer digunakan untuk merekam waktu navigasi, waktu sumber daya, dan waktu pengecatan secara otomatis (yang akan kita bahas nanti). Anda dapat memperoleh larik semua entri dalam buffer:

 performance.getEntries();

Secara default, sebagian besar browser menyediakan buffer yang menyimpan hingga 150 metrik sumber daya. Ini seharusnya cukup untuk sebagian besar penilaian, tetapi Anda dapat menambah atau mengurangi batas buffer jika diperlukan:

 // record 500 metrics performance.setResourceTimingBufferSize(500);

Tanda dapat dihapus dengan nama atau Anda dapat menentukan nilai kosong untuk menghapus semua tanda:

 performance.clearMarks('start:init');

Demikian pula, ukuran dapat dihapus dengan nama atau nilai kosong untuk menghapus semua:

 performance.clearMeasures();

Memantau Pembaruan Buffer Kinerja

PerformanceObserver dapat memantau perubahan pada buffer Kinerja dan menjalankan fungsi saat peristiwa tertentu terjadi. Sintaksnya akan familier jika Anda menggunakan MutationObserver untuk merespons pembaruan DOM atau IntersectionObserver untuk mendeteksi saat elemen di-scroll ke viewport.

Anda harus mendefinisikan fungsi pengamat dengan dua parameter:

  1. serangkaian entri pengamat yang telah terdeteksi, dan
  2. objek pengamat. Jika perlu, metode disconnect() dapat dipanggil untuk menghentikan pengamat.
 function performanceCallback(list, observer) { list.getEntries().forEach(entry => { console.log(`name : ${ entry.name }`); console.log(`type : ${ entry.type }`); console.log(`start : ${ entry.startTime }`); console.log(`duration: ${ entry.duration }`); }); }

Fungsi ini diteruskan ke objek PerformanceObserver baru. Metode observe() nya dilewatkan array Performance buffer entryTypes untuk diamati:

 let observer = new PerformanceObserver( performanceCallback ); observer.observe({ entryTypes: ['mark', 'measure'] });

Dalam contoh ini, menambahkan tanda atau ukuran baru menjalankan fungsi performanceCallback() . Meskipun hanya mencatat pesan di sini, ini dapat digunakan untuk memicu unggahan data atau membuat perhitungan lebih lanjut.

Mengukur Kinerja Cat

Paint Timing API hanya tersedia di JavaScript sisi klien dan secara otomatis mencatat dua metrik yang penting untuk Data Web Inti:

  1. first-paint: Browser sudah mulai menggambar halaman.
  2. first-contentful-paint: Peramban telah melukis item penting pertama dari konten DOM, seperti judul atau gambar.

Ini dapat diekstraksi dari buffer Kinerja ke array:

 const paintTimes = performance.getEntriesByType('paint');

Berhati-hatilah dalam menjalankan ini sebelum halaman dimuat sepenuhnya; nilai-nilai tidak akan siap. Tunggu acara window.load atau gunakan PerformanceObserver untuk memantau tipe entri paint .

Berjuang dengan downtime dan masalah WordPress? Kinsta adalah solusi hosting yang dirancang untuk menghemat waktu Anda! Lihat fitur kami

Contoh hasil:

 [ { "name": "first-paint", "entryType": "paint", "startTime": 812, "duration": 0 }, { "name": "first-contentful-paint", "entryType": "paint", "startTime": 856, "duration": 0 } ]

Pengecatan pertama yang lambat sering kali disebabkan oleh CSS atau JavaScript yang memblokir render. Kesenjangan ke first-contentful-paint bisa besar jika browser harus mengunduh gambar besar atau merender elemen kompleks.

Pengukuran Kinerja Sumber Daya

Pengaturan waktu jaringan untuk sumber daya seperti gambar, lembar gaya, dan file JavaScript secara otomatis direkam ke buffer Kinerja. Meskipun hanya ada sedikit yang dapat Anda lakukan untuk menyelesaikan masalah kecepatan jaringan (selain mengurangi ukuran file), ini dapat membantu menyoroti masalah dengan aset yang lebih besar, respons Ajax yang lambat, atau skrip pihak ketiga yang berkinerja buruk.

Array metrik PerformanceResourceTiming dapat diekstraksi dari buffer menggunakan:

 const resources = performance.getEntriesByType('resource');

Atau, Anda dapat mengambil metrik untuk suatu aset dengan meneruskan URL lengkapnya:

 const resource = performance.getEntriesByName('https://test.com/script.js');

Contoh hasil:

 [ { connectEnd: 195, connectStart: 195, decodedBodySize: 0, domainLookupEnd: 195, domainLookupStart: 195, duration: 2, encodedBodySize: 0, entryType: "resource", fetchStart: 195, initiatorType: "script", name: "https://test.com/script.js", nextHopProtocol: "h3", redirectEnd: 0, redirectStart: 0, requestStart: 195, responseEnd: 197, responseStart: 197, secureConnectionStart: 195, serverTiming: [], startTime: 195, transferSize: 0, workerStart: 195 } ]

Sifat-sifat berikut dapat diperiksa:

  • nama : URL Sumber Daya
  • jenis entri : "sumber daya"
  • initiatorType : Bagaimana sumber daya dimulai, seperti "skrip" atau "tautan"
  • serverTiming : Array objek PerformanceServerTiming yang dilewatkan oleh server di header HTTP Server-Timing (aplikasi sisi server Anda dapat mengirim metrik ke klien untuk analisis lebih lanjut)
  • startTime : Stempel waktu saat pengambilan dimulai
  • nextHopProtocol : Protokol jaringan yang digunakan
  • workerStart : Stempel waktu sebelum memulai Progressive Web App Service Worker (0 jika permintaan tidak dicegat oleh Service Worker)
  • redirectStart : Stempel waktu saat pengalihan dimulai
  • redirectEnd : Stempel waktu setelah byte terakhir dari respons pengalihan terakhir
  • fetchStart : Stempel waktu sebelum sumber daya diambil
  • domainLookupStart : Stempel waktu sebelum pencarian DNS
  • domainLookupEnd : Stempel waktu setelah pencarian DNS
  • connectStart : Stempel waktu sebelum membuat koneksi server
  • connectEnd : Stempel waktu setelah membuat koneksi server
  • secureConnectionStart : Stempel waktu sebelum jabat tangan SSL
  • requestStart : Stempel waktu sebelum browser meminta sumber daya
  • responseStart : Stempel waktu ketika browser menerima byte data pertama
  • responseEnd : Stempel waktu setelah menerima byte terakhir atau menutup koneksi
  • durasi : Perbedaan antara startTime dan responseEnd
  • transferSize : Ukuran sumber daya dalam byte termasuk header dan badan terkompresi
  • encodedBodySize : Badan sumber daya dalam byte sebelum dikompres
  • decodeBodySize : Badan sumber daya dalam byte setelah tidak dikompres

Skrip contoh ini mengambil semua permintaan Ajax yang diprakarsai oleh Fetch API dan mengembalikan total ukuran dan durasi transfer:

 const fetchAll = performance.getEntriesByType('resource') .filter( r => r.initiatorType === 'fetch') .reduce( (sum, current) => { return { transferSize: sum.transferSize += current.transferSize, duration: sum.duration += current.duration } }, { transferSize: 0, duration: 0 } );

Pengukuran Kinerja Navigasi

Pengaturan waktu jaringan untuk membongkar halaman sebelumnya dan memuat halaman saat ini secara otomatis direkam ke buffer Kinerja sebagai objek PerformanceNavigationTiming tunggal.

Ekstrak ke array menggunakan:

 const pageTime = performance.getEntriesByType('navigation');

…atau dengan meneruskan URL halaman ke .getEntriesByName() :

 const pageTiming = performance.getEntriesByName(window.location);

Metriknya identik dengan metrik untuk sumber daya tetapi juga menyertakan nilai khusus laman:

  • entryType : Misal "navigasi"
  • ketik : Baik “navigate”, “reload”, “back_forward”, atau “prerender”
  • redirectCount : Jumlah pengalihan
  • unloadEventStart : Stempel waktu sebelum acara pembongkaran dokumen sebelumnya
  • unloadEventEnd : Stempel waktu setelah acara pembongkaran dokumen sebelumnya
  • domInteractive : Timestamp ketika browser telah mem-parsing HTML dan membuat DOM
  • domContentLoadedEventStart : Stempel waktu sebelum acara DOMContentLoaded dokumen diaktifkan
  • domContentLoadedEventEnd : Stempel waktu setelah acara DOMContentLoaded dokumen selesai
  • domComplete : Stempel waktu setelah konstruksi DOM dan acara DOMContentLoaded selesai
  • loadEventStart : Stempel waktu sebelum acara pemuatan halaman diaktifkan
  • loadEventEnd : Stempel waktu setelah acara pemuatan halaman dan semua aset tersedia

Masalah umum meliputi:

  • Penundaan yang lama antara unloadEventEnd dan domInteractive . Ini bisa menunjukkan respons server yang lambat.
  • Penundaan yang lama antara domContentLoadedEventStart dan domComplete . Ini bisa menunjukkan bahwa skrip pembuka halaman terlalu lambat.
  • Penundaan yang lama antara domComplete dan loadEventEnd . Hal ini dapat menunjukkan bahwa halaman memiliki terlalu banyak aset atau beberapa terlalu lama untuk dimuat.

Perekaman dan Analisis Kinerja

Performance API memungkinkan Anda untuk menyusun data penggunaan dunia nyata dan mengunggahnya ke server untuk analisis lebih lanjut. Anda dapat menggunakan layanan pihak ketiga seperti Google Analytics untuk menyimpan data, tetapi ada risiko skrip pihak ketiga dapat diblokir atau menimbulkan masalah kinerja baru. Solusi Anda sendiri dapat disesuaikan dengan kebutuhan Anda untuk memastikan pemantauan tidak memengaruhi fungsi lainnya.

Waspadalah terhadap situasi di mana statistik tidak dapat ditentukan — mungkin karena pengguna menggunakan browser lama, memblokir JavaScript, atau di belakang proxy perusahaan. Memahami data apa yang hilang bisa lebih bermanfaat daripada membuat asumsi berdasarkan informasi yang tidak lengkap.

Idealnya, skrip analisis Anda tidak akan berdampak negatif pada kinerja dengan menjalankan penghitungan yang rumit atau mengunggah data dalam jumlah besar. Pertimbangkan untuk menggunakan pekerja web dan meminimalkan penggunaan panggilan penyimpanan lokal sinkron. Itu selalu memungkinkan untuk memproses data mentah secara batch nanti.

Terakhir, waspadalah terhadap outlier seperti perangkat dan koneksi yang sangat cepat atau sangat lambat yang berdampak buruk pada statistik. Misalnya, jika sembilan pengguna memuat halaman dalam dua detik tetapi yang kesepuluh mengalami unduhan 60 detik, latensi rata-rata menjadi hampir 8 detik. Metrik yang lebih realistis adalah angka median (2 detik) atau persentil ke-90 (9 dari setiap 10 pengguna mengalami waktu muat 2 detik atau kurang).

Ringkasan

Kinerja web tetap menjadi faktor penting bagi pengembang. Pengguna mengharapkan situs dan aplikasi responsif di sebagian besar perangkat. Search Engine Optimization juga dapat terpengaruh karena situs yang lebih lambat diturunkan di Google.
Semua yang perlu Anda ketahui untuk memulai Performance API ada di sini Klik untuk Tweet
Ada banyak alat pemantauan kinerja di luar sana, tetapi sebagian besar menilai kecepatan eksekusi sisi server atau menggunakan sejumlah klien yang mampu untuk menilai rendering browser. Performance API menyediakan cara untuk menyusun metrik pengguna nyata yang tidak mungkin dihitung dengan cara lain.