Dalam codelab ini, Anda akan mempelajari cara menggunakan Google Analytics dan User Timings API untuk mengukur performa situs atau aplikasi Anda di dunia nyata dan mengoptimalkannya untuk meningkatkan pengalaman pengguna.
Alat seperti WebPagetest.org adalah awal yang baik untuk pengoptimalan performa, tetapi pengujian performa situs yang sebenarnya akan selalu berupa data nyata dari pengguna sebenarnya.
Jika Anda mengoperasikan situs, kemungkinan besar Anda sudah menggunakan Google Analytics untuk mengukur traffic serta hal-hal seperti penggunaan perangkat dan browser. Hanya dengan sedikit kode tambahan, Anda dapat menambahkan metrik performa ke dalam campuran.
Yang akan Anda pelajari
- Cara mengukur metrik performa secara akurat dan efektif menggunakan User Timings API
- Cara mengirim data tersebut ke Google Analytics agar dapat dimasukkan ke dalam laporan Anda
Yang Anda butuhkan
- Browser dengan konsol developer
- Server Web untuk Chrome, atau gunakan server web pilihan Anda sendiri
- Kode contoh
- Editor teks
- (Opsional) akun Google Analytics
Bagaimana Anda akan menggunakan tutorial ini?
Bagaimana penilaian Anda terhadap pengalaman Anda dalam membuat situs atau aplikasi web?
Anda dapat mendownload semua kode contoh ke komputer...
...atau clone repositori GitHub dari command line.
git clone https://github.com/googlecodelabs/performance-analytics.git
Kode contoh dibagi menjadi subdirektori yang sesuai dengan setiap langkah bernomor dalam lab kode ini. Anda dapat menggunakannya untuk dengan mudah berpindah-pindah di codelab atau memverifikasi bahwa penerapan Anda sudah benar.
Jika memiliki akses ke program perbandingan, Anda dapat menggunakannya untuk melihat dengan tepat apa yang berubah dari langkah ke langkah.
Dalam codelab ini, Anda akan menggunakan satu file HTML yang memuat aset berikut:
- Font web
- Stylesheet
- Gambar
- JavaScript
Anda akan menulis kode baru yang mengukur metrik performa utama untuk setiap jenis aset ini.
Pertimbangan performa aset
Jika pernah membaca apa pun tentang pengoptimalan performa, Anda mungkin sudah tahu bahwa setiap jenis aset ini memiliki keunikan masing-masing dan dapat memengaruhi keseluruhan performa yang dirasakan dengan berbagai cara.
CSS
Misalnya, stylesheet memblokir rendering semua elemen di DOM yang muncul setelahnya, yang berarti browser harus membuat permintaan untuk stylesheet, mendownloadnya, dan menguraikannya sebelum dapat merender konten apa pun di DOM yang muncul setelahnya. Oleh karena itu, sebaiknya tempatkan stylesheet di <head> dokumen. Dan karena sifat pemblokiran CSS, sering kali juga direkomendasikan untuk hanya menempatkan CSS penting di <head> dan memuat CSS yang tidak penting secara asinkron setelahnya.
JavaScript
Di sisi lain, JavaScript tidak memblokir rendering, tetapi memblokir parsing dan konstruksi DOM. Hal ini diperlukan karena JavaScript dapat mengubah DOM, yang berarti setiap kali browser melihat tag <script> (tidak termasuk skrip asinkron), browser harus menjalankan kode sebelum melanjutkan ke tag berikutnya. Jika tag <script> mereferensikan file JavaScript eksternal, tag tersebut harus mendownload dan mengeksekusi kode sebelum melanjutkan.
Oleh karena itu, sering kali direkomendasikan agar JavaScript Anda dimuat tepat sebelum tag </body> penutup, sehingga sebagian besar DOM tersedia secepat mungkin.
Font web
Jika memuat font web, Anda juga dapat memilih untuk memblokir rendering dokumen hingga font tersedia untuk digunakan. Dalam hal ini, penting untuk memahami berapa lama waktu yang dibutuhkan pengguna Anda. Font web mungkin dimuat dengan cepat untuk Anda, tetapi sangat lambat untuk sebagian besar orang yang mengunjungi situs Anda. Itulah sebabnya pengukuran dan pengambilan keputusan berdasarkan data nyata sangat penting.
Gambar
Terakhir, gambar dapat membuat situs menjadi lebih menarik, tetapi sering kali membutuhkan waktu pemuatan yang paling lama. Memahami arti sebenarnya dari hal ini dan dapat menemukan korelasi antara pola penggunaan dan waktu pemuatan halaman sangat penting untuk memahami cara mengoptimalkan.
Langkah pertama dalam lab kode ini adalah melihat tampilan halaman demo sebelum menambahkan kode pengukuran performa.
Untuk melihat demo, buat folder baru dan tambahkan file di dalamnya yang bernama index.html. Kemudian, salin dan tempel kode di bawah ke dalam file index.html.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Performance Analytics Demo</title>
<!-- Start fonts -->
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700,400italic" rel="stylesheet">
<!-- End fonts -->
<!-- Start CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<style>
body { font-family: Roboto, sans-serif; margin: 1em; }
img { float: left; height: auto; width: 33.33%; }
.gallery { overflow: hidden; }
</style>
<!-- End CSS -->
</head>
<body>
<div class="container">
<!-- Start images -->
<div class="gallery">
<img src="http://lorempixel.com/380/200/animals/1/">
<img src="http://lorempixel.com/380/200/animals/2/">
<img src="http://lorempixel.com/380/200/animals/3/">
</div>
<!-- End images -->
<h1>Performance Analytics Demo</h1>
<p>Real performance data from real users.</p>
</div>
<!-- Start JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<!-- End JavaScript -->
</body>
</html>
Selanjutnya, buka Web Server for Chrome dan mulai server lokal di direktori yang baru saja Anda buat. Pastikan Anda mencentang "tampilkan index.html secara otomatis".
Sekarang Anda dapat membuka http://127.0.0.1:8887/ di browser dan melihat file demo. Ini akan terlihat seperti berikut:
Setelah halaman demo berjalan, luangkan waktu untuk melihat kode dan melihat semua jenis aset yang dimuat. Pada beberapa langkah berikutnya, Anda akan menambahkan kode untuk mengukur kapan aset ini dimuat dan dapat berinteraksi dengan pengguna.
Seperti yang disebutkan di bagian pertimbangan performa aset sebelumnya, CSS memblokir rendering elemen DOM serta eksekusi skrip yang muncul setelahnya di DOM.
File demo yang baru saja Anda buat berisi CSS berikut, yang merujuk Bootstrap dan beberapa gaya inline.
<!-- Start CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<style>
body { font-family: Roboto, sans-serif; margin: 1em; }
img { float: left; height: auto; width: 33.33%; }
.gallery { overflow: hidden; }
</style>
<!-- End CSS -->
Karena CSS memblokir rendering elemen DOM dan eksekusi skrip, Anda dapat menentukan kapan CSS selesai memblokir dengan menambahkan tag <script>
segera setelah CSS yang menyimpan waktu saat ini.
Anda dapat melakukannya dengan membuat variabel dan menetapkan new Date()
ke variabel tersebut, tetapi berkat User Timings API, ada cara yang jauh lebih mudah: metode performance.mark
.
Untuk menandai kapan CSS selesai memblokir rendering dan eksekusi skrip, tambahkan baris kode berikut tepat sebelum komentar <!-- End CSS -->
penutup.
<script>performance.mark('css:unblock');</script>
Metode performance.mark
membuat stempel waktu resolusi tinggi pada waktu yang tepat ini, dan mengaitkannya dengan nama apa pun yang diteruskan ke metode. Dalam hal ini, Anda memberi nama tanda "css:unblock".
Metode performance.mark
berjalan seiring dengan metode performance.measure
, yang digunakan untuk menghitung perbedaan waktu antara dua tanda (selain tanda yang Anda buat, Anda juga dapat menggunakan tanda yang dibuat browser secara otomatis untuk berbagai titik di Navigation Timing API).
Fungsi utilitas berikut mengukur dan menampilkan durasi waktu antara tanda yang telah Anda tambahkan dan tanda responseEnd yang dibuat oleh Navigation Timing API.
function measureDuration(mark, opt_reference) {
var reference = opt_reference || 'responseEnd';
var name = reference + ':' + mark;
// Clears any existing measurements with the same name.
performance.clearMeasures(name);
// Creates a new measurement from the reference point to the specified mark.
// If more than one mark with this name exists, the most recent one is used.
performance.measure(name, reference, mark);
// Gets the value of the measurement just created.
var measure = performance.getEntriesByName(name)[0];
// Returns the measure duration.
return measure.duration;
}
Untuk mulai menggunakan fungsi utilitas ini, buat file baru bernama perf-analytics.js
(di direktori yang sama dengan file index.html
), lalu salin dan tempel kode di atas ke dalamnya.
Setelah fungsi ini ditentukan, Anda dapat memanggilnya dan meneruskan nama tanda "css:unblock". Agar tidak mengganggu pemuatan resource lain, Anda harus menunda menjalankan pengukuran ini hingga setelah peristiwa pemuatan jendela diaktifkan.
Setelah Anda menulis fungsi untuk memanggil kode ini, file perf-analytics.js
Anda akan terlihat seperti ini:
window.onload = function() {
measureCssUnblockTime();
};
/**
* Calculates the time duration between the responseEnd timing event and when
* the CSS stops blocking rendering, then logs that value to the console.
*/
function measureCssUnblockTime() {
console.log('CSS', 'unblock', measureDuration('css:unblock'));
}
/**
* Accepts a mark name and an optional reference point in the navigation timing
* API and returns the time duration between the reference point and the last
* mark (chronologically).
* @param {string} mark The mark name.
* @param {string=} opt_reference An optional reference point from the
* navigation timing API. Defaults to 'responseEnd'.
* @return {number} The time duration
*/
function measureDuration(mark, opt_reference) {
var reference = opt_reference || 'responseEnd';
var name = reference + ':' + mark;
// Clears any existing measurements with the same name.
performance.clearMeasures(name);
// Creates a new measurement from the reference point to the specified mark.
// If more than one mark with this name exists, the most recent one is used.
performance.measure(name, reference, mark);
// Gets the value of the measurement just created.
var measure = performance.getEntriesByName(name)[0];
// Returns the measure duration.
return measure.duration;
}
Terakhir, Anda harus memuat skrip perf-analytics.js
dari index.html
. Untuk melakukannya, tambahkan tag skrip berikut ke dokumen utama Anda. Pastikan untuk menambahkannya terakhir agar tidak mengganggu pemuatan resource lain.
<!-- Start performance analytics -->
<script async src="perf-analytics.js"></script>
<!-- End performance analytics -->
Setelah Anda menyelesaikan langkah ini, kode Anda akan cocok dengan yang ada di direktori 01-css
repositori codelab.
Jika Anda memuat halaman di browser dan membuka konsol developer, Anda akan melihat output seperti berikut:
Font web biasanya dimuat melalui stylesheet eksternal, seperti yang terlihat dalam file demo awal:
<!-- Start fonts -->
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700,400italic" rel="stylesheet">
<!-- End fonts -->
Karena ini adalah tag <link>
ke file CSS, mungkin tampak bahwa menentukan kapan font dimuat dan siap digunakan sesederhana menambahkan tanda di dalam tag <script>
segera setelah <link>
, seperti pada langkah 1.
Sayangnya, tidak sesederhana ini.
Stylesheet memblokir eksekusi JavaScript karena konten stylesheet digunakan untuk membuat CSSOM, dan karena JavaScript yang dimuat mungkin perlu mengakses CSSOM, eksekusi harus ditunda hingga CSSOM dibuat sepenuhnya.
Masalahnya adalah browser dapat membuat CSSOM tanpa benar-benar mendownload font, yang berarti bahwa jika Anda menambahkan tanda melalui tag skrip inline ke DOM segera setelah tag <link> stylesheet font, kemungkinan tanda akan terjadi sebelum font dimuat sepenuhnya.
Hingga peristiwa pemuatan font tersedia di browser, JavaScript diperlukan untuk menentukan kapan font benar-benar aktif dan siap digunakan di halaman. Untungnya, memuat font melalui JavaScript juga meningkatkan performa, karena tidak memerlukan permintaan pemblokiran tambahan ke file CSS.
Sebagian besar font web (termasuk font Google, Typekit, dan font.com) dapat dimuat melalui skrip webfont.js, yang dikembangkan bersama oleh Google dan Typekit.
Untuk memperbarui dokumen utama agar menggunakan webfont.js untuk memuat font (bukan tag <link>), ganti bagian font kode dengan kode berikut:
<!-- Start fonts -->
<script>
window.WebFontConfig = {
google: {families: ['Roboto:400,700,400italic']},
timeout: 10000,
active: function() {
performance.mark('fonts:active');
}
};
</script>
<script async src="https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js"></script>
<!-- End fonts -->
Ada dua hal penting yang perlu diperhatikan tentang kode di atas:
- Hal ini akan membuat tanda "fonts:active" di callback aktif, sehingga Anda dapat mengukur berapa lama waktu yang dibutuhkan font untuk dimuat.
- Tag
<script>
yang memuat webfonts.js berisi atributasync
, sehingga tidak akan memblokir penguraian atau rendering dokumen lainnya (yang tidak berlaku untuk tag<link>
).
Meskipun kode di atas membuat tanda "fonts:active", mengukur tanda ini dan mencatatnya ke konsol tidak sesederhana tanda "css:unblock". Alasannya adalah pemuatan font kini terjadi secara asinkron, jadi jika Anda mencoba mengukur tanda "fonts:active" di handler window.onload
(seperti yang Anda lakukan dengan "css:unblock"), kemungkinan besar font belum dimuat.
Untuk mengatasi masalah ini, Anda dapat membuat promise yang diselesaikan setelah font dimuat. Fungsi berikut akan melakukannya untuk Anda. Salin dan tempel ke dalam file perf-analytics.js:
/**
* Creates a promise that is resolved once the web fonts are fully load or
* is reject if the fonts fail to load. The resolved callback calculates the
* time duration between the responseEnd timing event and when the web fonts
* are downloaded and active. If an error occurs loading the font, this fact
* is logged to the console.
*/
function measureWebfontPerfAndFailures() {
new Promise(function(resolve, reject) {
// The classes `wf-active` or `wf-inactive` are added to the <html>
// element once the fonts are loaded (or error).
var loaded = /wf-(in)?active/.exec(document.documentElement.className);
var success = loaded && !loaded[1]; // No "in" in the capture group.
// If the fonts are already done loading, resolve immediately.
// Otherwise resolve/reject in the active/inactive callbacks, respectively.
if (loaded) {
success ? resolve() : reject();
}
else {
var originalAciveCallback = WebFontConfig.active;
WebFontConfig.inactive = reject;
WebFontConfig.active = function() {
originalAciveCallback();
resolve();
};
// In case the webfont.js script fails to load, always reject the
// promise after the timeout amount.
setTimeout(reject, WebFontConfig.timeout);
}
})
.then(function() {
console.log('Fonts', 'active', measureDuration('fonts:active'));
})
.catch(function() {
console.error('Error loading web fonts')
});
}
Perbarui juga pengendali window.onload
untuk memanggil fungsi baru ini
window.onload = function() {
measureCssUnblockTime();
measureWebfontPerfAndFailures();
};
Setelah Anda menyelesaikan langkah ini, kode Anda akan cocok dengan yang ada di direktori 02-fonts
repositori codelab.
Jika Anda memuat halaman di browser dan membuka konsol developer, Anda akan melihat output seperti berikut:
Mengetahui kapan gambar terlihat tidak sesederhana yang terlihat. Anda tahu dari langkah-langkah sebelumnya bahwa stylesheet dan tag <script>
sinkron dapat memblokir rendering, parsing, dan eksekusi skrip. Yang mungkin tidak Anda ketahui adalah bahwa keduanya tidak memblokir pemindai pramuat browser.
Pemindai pramuat adalah sesuatu yang diterapkan semua browser modern sebagai salah satu dari banyak upaya untuk meningkatkan performa, bahkan di situs yang tidak berorientasi pada performa yang berisi banyak aset pemblokiran. Idenya adalah meskipun beberapa aset dapat memblokir parsing atau rendering atau eksekusi skrip, aset tersebut tidak harus memblokir download. Jadi, browser memindai file HTML sebelum mulai membuat DOM dan mencari aset yang dapat mulai didownload dengan segera.
Sejauh menyangkut gambar, hal ini berarti ada kemungkinan besar gambar Anda sudah didownload pada saat ditambahkan ke DOM. Hal ini juga berarti bahwa titik saat gambar didownload belum tentu merupakan metrik performa yang baik. Metrik performa yang harus Anda perhatikan adalah titik saat gambar terlihat oleh pengguna.
Saat gambar didownload sebelum ditambahkan ke DOM, titik saat gambar menjadi terlihat adalah titik saat gambar berada di DOM. Di sisi lain, jika gambar tidak didownload sebelum ditambahkan ke DOM, titik saat gambar menjadi terlihat adalah saat handler onload
-nya diaktifkan.
Jadi, untuk mengetahui kapan gambar terlihat, Anda harus menangani kedua kasus tersebut.
Anda dapat melakukannya dengan menambahkan tanda di setiap pengendali onload gambar serta di tag <script> inline segera setelah gambar terakhir di DOM. Idenya adalah tanda yang terjadi terakhir akan menjadi tanda yang menunjukkan kapan semua gambar terlihat.
Untuk menambahkan tanda saat gambar dimuat dan saat dirender, perbarui kode gambar di index.html
sebagai berikut:
<!-- Start images -->
<div class="gallery">
<img onload="performance.mark('img:visible')" src="http://lorempixel.com/380/200/animals/1/">
<img onload="performance.mark('img:visible')" src="http://lorempixel.com/380/200/animals/2/">
<img onload="performance.mark('img:visible')" src="http://lorempixel.com/380/200/animals/3/">
</div>
<script>performance.mark('img:visible')</script>
<!-- End images -->
Karena metode performance.measure
untuk nama tanda tertentu akan selalu menggunakan tanda terakhir (jika menemukan beberapa tanda dengan nama yang sama), fungsi utilitas measureDuration
dalam file perf-analytics.js
dapat digunakan untuk ini tanpa modifikasi tambahan:
/**
* Calculates the time duration between the responseEnd timing event and when
* all images are loaded and visible on the page, then logs that value to the
* console.
*/
function measureImagesVisibleTime() {
console.log('Images', 'visible', measureDuration('img:visible'));
}
Tambahkan fungsi di atas ke file perf-analytics.js
, lalu perbarui pengendali window.onload
untuk memanggilnya:
window.onload = function() {
measureCssBlockTime();
measureWebfontPerfAndFailures();
measureImagesVisibleTime();
};
Setelah Anda menyelesaikan langkah ini, kode Anda akan cocok dengan yang ada di direktori 03-images
repositori codelab.
Jika Anda memuat halaman di browser dan membuka konsol developer, Anda akan melihat output seperti berikut:
Karena tag <script>
tanpa atribut async
memblokir penguraian DOM hingga tag tersebut didownload dan dieksekusi, Anda dapat menentukan titik saat semua skrip telah selesai dieksekusi dengan menambahkan tanda di tag skrip inline segera setelah <script>
sinkron terakhir di DOM.
Perhatikan bahwa penggunaan handler onload
tidak akan berfungsi dalam kasus ini karena browser harus mengeksekusi skrip setelah memuatnya, dan hal itu membutuhkan waktu. Skrip yang cepat dimuat tetapi lambat dieksekusi bisa sama buruknya dengan skrip yang lambat dimuat.
Untuk melacak kapan semua JavaScript dimuat dan dieksekusi dalam dokumen utama, perbarui bagian JavaScript di index.html
dengan kode berikut:
<!-- Start JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script>performance.mark('js:execute');</script>
<!-- End JavaScript -->
Tindakan ini akan menambahkan tanda bernama "js:execute" segera setelah skrip untuk plugin jQuery dan Bootstrap didownload dan selesai dieksekusi.
Untuk mengukur durasi yang diperlukan, tambahkan fungsi berikut ke perf-analytics.js
:
/**
* Calculates the time duration between the responseEnd timing event and when
* all synchronous JavaScript files have been downloaded and executed, then
* logs that value to the console.
*/
function measureJavaSciptExecutionTime() {
console.log('JavaScript', 'execute', measureDuration('js:execute'));
}
Kemudian, panggil dari pengendali window.onload
:
window.onload = function() {
measureCssBlockTime();
measureWebfontPerfAndFailures();
measureImagesVisibleTime();
measureJavaSciptExecutionTime();
};
Setelah Anda menyelesaikan langkah ini, kode Anda akan cocok dengan yang ada di direktori 04-javascript
repositori codelab.
Jika Anda memuat halaman di browser dan membuka konsol developer, Anda akan melihat output seperti berikut:
Tidak semua browser mendukung promise JavaScript atau User Timing API, dan jika Anda menjalankan kode yang telah Anda tulis sejauh ini di browser tanpa dukungan untuk salah satu fitur ini, Anda akan mendapatkan error.
Untuk mengatasi hal ini, Anda dapat menggunakan deteksi fitur. Tambahkan sedikit kode berikut tepat sebelum bagian font. Baris JavaScript ini mendeteksi dukungan untuk metode performance.mark
, jadi harus ditambahkan ke halaman sebelum metode tersebut digunakan:
<!-- Start feature detects -->
<script>window.__perf = window.performance && performance.mark;</script>
<!-- End feature detects -->
Selanjutnya, di mana pun di index.html
tempat Anda memanggil performance.mark
, awali dengan deteksi fitur. Berikut adalah contoh yang memperbarui kode di blok gambar, tetapi Anda harus memastikan untuk memperbarui bagian lainnya juga.
<!-- Start images -->
<div class="gallery">
<img onload="__perf && performance.mark('img:visible')" src="http://lorempixel.com/380/200/animals/1/">
<img onload="__perf && performance.mark('img:visible')" src="http://lorempixel.com/380/200/animals/2/">
<img onload="__perf && performance.mark('img:visible')" src="http://lorempixel.com/380/200/animals/3/">
</div>
<script>__perf && performance.mark('img:visible')</script>
<!-- End images -->
Setelah variabel __perf
ditetapkan di window
, Anda juga dapat menggunakannya di perf-analytics.js
untuk memastikan Anda tidak memanggil metode yang tidak didukung di browser saat ini.
Fungsi measureDuration
harus diperbarui untuk menambahkan kondisi berikut:
function measureDuration(mark, opt_reference) {
if (window.__perf) {
// ...
}
}
Terakhir, karena tidak semua browser mendukung promise JavaScript, fungsi measureWebfontPerfAndFailures
juga harus di-wrap dalam kondisi:
function measureWebfontPerfAndFailures() {
if (window.Promise) {
// ...
}
}
Sekarang Anda dapat menjalankan kode di browser mana pun tanpa masalah.
Setelah Anda menyelesaikan langkah ini, kode Anda akan cocok dengan yang ada di direktori 05-feature-detects
repositori codelab.
Langkah terakhir dalam codelab ini adalah mengambil data yang dicatat ke konsol dan mengirimkannya ke Google Analytics. Sebelum dapat mengirim data ke Google Analytics, Anda harus menambahkan library analytics.js dan cuplikan pelacakan default ke halaman Anda.
Tambahkan kode berikut ke index.html
setelah blok JavaScript utama, tetapi sebelum skrip perf-analytics.js
dimuat:
<!-- Start analytics tracking snippet -->
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<script async src="https://www.google-analytics.com/analytics_debug.js"></script>
<!-- End analytics tracking snippet -->
Jika Anda pernah menambahkan Google Analytics ke situs sebelumnya, Anda akan tahu bahwa Anda harus mengganti placeholder "UA-XXXXX-Y" dengan ID pelacakan yang Anda terima saat membuat properti baru di Google Analytics.
Cuplikan pelacakan analytics.js melakukan empat hal utama:
- Membuat elemen
<script>
asinkron yang mendownload library JavaScript analytics.js. - Melakukan inisialisasi fungsi
ga()
global (disebut antrean perintah ga()) yang memungkinkan Anda menjadwalkan perintah yang akan dijalankan setelah library analytics.js dimuat dan siap digunakan. - Menambahkan perintah ke antrean perintah
ga()
untuk membuat objek pelacak baru untuk properti yang ditentukan melalui parameter'UA-XXXXX-Y'. - Menambahkan perintah lain ke antrean perintah
ga()
untuk mengirim kunjungan halaman ke Google Analytics untuk halaman saat ini.
Meskipun data yang dikumpulkan dari tayangan halaman saja berguna, data tersebut tidak menceritakan keseluruhan kisah. Untuk mendapatkan gambaran yang lebih baik tentang pengalaman pengguna di situs atau aplikasi Anda, Anda harus mengirimkan data interaksi tambahan ke Google Analytics.
Google Analytics mendukung beberapa jenis data interaksi: tayangan halaman, peristiwa, interaksi sosial, pengecualian, dan (yang terakhir) waktu pengguna. Untuk mengirim data waktu pengguna ke Google Analytics, Anda dapat menggunakan tanda tangan perintah berikut:
ga('send', 'timing', timingCategory, timingVar, timingValue);
Dengan timingCategory
adalah string yang memungkinkan Anda mengatur hit waktu ke dalam grup logis, timingVar
adalah variabel yang Anda ukur, dan timingValue
adalah durasi waktu sebenarnya dalam milidetik.
Untuk melihat cara kerjanya dalam praktik, pernyataan console.log
dalam fungsi measureCssUnblockTime
dapat diupdate sebagai berikut:
ga('send', 'timing', 'CSS', 'unblock', measureDuration('css:unblock'));
Meskipun kode di atas akan berfungsi dalam beberapa situasi, ada dua hal penting yang perlu diperhatikan:
- Langkah sebelumnya memperbarui fungsi
measureDuration
agar hanya berjalan jika browser mendukung User Timings API, yang berarti terkadang akan menampilkanundefined
. Karena tidak ada alasan untuk mengirim data yang tidak ditentukan ke Google Analytics (dalam beberapa kasus, hal ini bahkan dapat mengacaukan laporan Anda), Anda hanya boleh mengirim hit waktu ini jikameasureDuration
menampilkan nilai. - Jika
measureDuration
menampilkan nilai, nilai tersebut adalahDOMHighResTimeStamp
, yang akan memiliki presisi lebih dari milidetik. KarenatimingValue
di Google Analytics harus berupa bilangan bulat, Anda harus membulatkan nilai yang ditampilkan olehmeasureDuration
.
Untuk memperhitungkan kesalahan ini, perbarui pernyataan return dalam fungsi measureDuration untuk membulatkan nilai return:
function measureDuration(mark, opt_reference) {
if (window.__perf) {
// ...
return Math.round(measure.duration);
}
}
Perbarui perintah pengaturan waktu agar hanya berjalan jika ada nilai untuk metrik yang dimaksud. Sebagai contoh, fungsi measureCssUnblockTime
harus diupdate menjadi seperti ini:
function measureCssUnblockTime() {
var cssUnblockTime = measureDuration('css:unblock');
if (cssUnblockTime) {
ga('send', 'timing', 'CSS', 'unblock', cssUnblockTime);
}
}
Anda harus melakukan pembaruan serupa pada semua fungsi pengukuran lainnya. Setelah selesai, file perf-analytics.js akhir akan terlihat seperti ini:
window.onload = function() {
measureCssUnblockTime();
measureWebfontPerfAndFailures();
measureImagesVisibleTime();
measureJavaSciptExecutionTime();
};
/**
* Calculates the time duration between the responseEnd timing event and when
* the CSS stops blocking rendering, then sends this measurement to Google
* Analytics via a timing hit.
*/
function measureCssUnblockTime() {
var cssUnblockTime = measureDuration('css:unblock');
if (cssUnblockTime) {
ga('send', 'timing', 'CSS', 'unblock', cssUnblockTime);
}
}
/**
* Calculates the time duration between the responseEnd timing event and when
* the web fonts are downloaded and active, then sends this measurement to
* Google Analytics via a timing hit. If an error occurs loading the font, an
* error event is sent to Google Analytics.
*/
function measureWebfontPerfAndFailures() {
if (window.Promise) {
new Promise(function(resolve, reject) {
var loaded = /wf-(in)?active/.exec(document.documentElement.className);
var success = loaded && !loaded[1]; // No "in" in the capture group.
if (loaded) {
success ? resolve() : reject();
}
else {
var originalAciveCallback = WebFontConfig.active;
WebFontConfig.inactive = reject;
WebFontConfig.active = function() {
originalAciveCallback();
resolve();
};
// In case the webfont.js script failed to load.
setTimeout(reject, WebFontConfig.timeout);
}
})
.then(function() {
var fontsActiveTime = measureDuration('fonts:active');
if (fontsActiveTime) {
ga('send', 'timing', 'Fonts', 'active', fontsActiveTime);
}
})
.catch(function() {
ga('send', 'event', 'Fonts', 'error');
});
}
}
/**
* Calculates the time duration between the responseEnd timing event and when
* all images are loaded and visible on the page, then sends this measurement
* to Google Analytics via a timing hit.
*/
function measureImagesVisibleTime() {
var imgVisibleTime = measureDuration('img:visible');
if (imgVisibleTime) {
ga('send', 'timing', 'Images', 'visible', imgVisibleTime);
}
}
/**
* Calculates the time duration between the responseEnd timing event and when
* all synchronous JavaScript files are downloaded and executed, then sends
* this measurement to Google Analytics via a timing hit.
*/
function measureJavaSciptExecutionTime() {
var jsExecuteTime = measureDuration('js:execute');
if (jsExecuteTime) {
ga('send', 'timing', 'JavaScript', 'execute', jsExecuteTime);
}
}
/**
* Accepts a mark name and an optional reference point in the navigation timing
* API and returns the time duration between the reference point and the last
* mark (chronologically). The return value is rounded to the nearest whole
* number to be compatible with Google Analytics.
* @param {string} mark The mark name.
* @param {string=} opt_reference An optional reference point from the
* navigation timing API. Defaults to 'responseEnd'.
* @return {?number} The time duration as an integer or undefined if no
* matching marks can be found.
*/
function measureDuration(mark, opt_reference) {
if (window.__perf) {
var reference = opt_reference || 'responseEnd';
var name = reference + ':' + mark;
// Clears any existing measurements with the same name.
performance.clearMeasures(name);
// Creates a new measurement from the reference point to the specified mark.
// If more than one mark with this name exists, the most recent one is used.
performance.measure(name, reference, mark);
// Gets the value of the measurement just created.
var measure = performance.getEntriesByName(name)[0];
// Returns the measure duration.
return Math.round(measure.duration);
}
}
Dan file index.html akhir akan terlihat seperti ini:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Performance Analytics Demo</title>
<!-- Start navigation timing feature detect -->
<script>window.__perf = window.performance && performance.mark;</script>
<!-- End navigation timing feature detect -->
<!-- Start fonts -->
<script>
window.WebFontConfig = {
google: {families: ['Roboto:400,700,400italic']},
timeout: 10000,
active: function() {
__perf && performance.mark('fonts:active');
}
};
</script>
<script async src="https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js"></script>
<!-- End fonts -->
<!-- Start CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<style>
body { font-family: Roboto, sans-serif; margin: 1em; }
img { float: left; height: auto; width: 33.33%; }
.gallery { overflow: hidden; }
</style>
<script>__perf && performance.mark('css:unblock');</script>
<!-- End CSS -->
</head>
<body>
<div class="container">
<!-- Start images -->
<div class="gallery">
<img onload="__perf && performance.mark('img:visible')" src="http://lorempixel.com/380/200/animals/1/">
<img onload="__perf && performance.mark('img:visible')" src="http://lorempixel.com/380/200/animals/2/">
<img onload="__perf && performance.mark('img:visible')" src="http://lorempixel.com/380/200/animals/3/">
</div>
<script>__perf && performance.mark('img:visible')</script>
<!-- End images -->
<h1>Performance Analytics Demo</h1>
<p>Real performance data from real users.</p>
</div>
<!-- Start JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script>__perf && performance.mark('js:execute');</script>
<!-- End JavaScript -->
<!-- Start analytics tracking snippet -->
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<script async src="https://www.google-analytics.com/analytics.js"></script>
<!-- End analytics tracking snippet -->
<!-- Start performance analytics -->
<script async src="perf-analytics.js"></script>
<!-- End performance analytics -->
</body>
</html>
Jika Anda memuat halaman ini dan melihat permintaan di panel jaringan, Anda akan melihat sesuatu seperti berikut:
Hal ini berguna, tetapi akan merepotkan jika melihat data ini sebagai permintaan yang dienkode URL. Selain itu, jika karena alasan apa pun Anda tidak melihat permintaan ini, akan sangat sulit untuk melacak di mana kegagalan terjadi.
Pendekatan yang lebih baik saat mengembangkan secara lokal adalah menggunakan versi debug analytics.js, yang akan mencatat informasi proses debug yang berguna ke konsol saat setiap perintah analytics.js dijalankan. Jika Anda
Perbarui URL analytics.js di index.html
menjadi analytics_debug.js
dan buka konsol browser, Anda akan melihat pernyataan yang dicetak seperti ini:
Setelah memahami cara menerapkan pengukuran performa untuk halaman demo ini, Anda dapat mencoba menambahkannya ke situs Anda sendiri, dengan mengirimkan data pengguna sebenarnya ke Google Analytics.
Pelaporan data yang telah Anda kumpulkan
Setelah mengumpulkan data performa selama beberapa hari, Anda dapat membuat laporan tentang data tersebut untuk mendapatkan insight yang dapat ditindaklanjuti tentang seberapa cepat situs dan sumber dayanya dimuat untuk pengguna sebenarnya.
Untuk membuka laporan Waktu Pengguna di Google Analytics, klik tab Pelaporan di bagian atas dan pilih "Perilaku > Kecepatan Situs > Waktu Pengguna" dari navigasi sidebar (atau ikuti petunjuk untuk melihat laporan Waktu Pengguna dari Pusat Bantuan).
Saat memuat laporan Waktu Pengguna di Google Analytics, Anda akan dapat melihat kategori waktu yang sesuai dengan data yang Anda kirim. Klik salah satu opsi tersebut untuk melihat visualisasi mendetail dari data pengaturan waktu Anda. Gambar berikut adalah contoh waktu pemuatan font di situs sebenarnya menggunakan Google Fonts selama 24 jam terakhir.
Selamat! Anda berhasil menyelesaikan lab kode ini. Jika Anda ingin mempelajari lebih dalam, bagian berikutnya akan memberi Anda beberapa saran tentang cara membangun kode ini untuk mendapatkan lebih banyak insight.
Metrik performa yang dibahas dalam codelab ini sangat penting untuk mengukur cara situs Anda dimuat bagi pengguna sebenarnya, tetapi ini hanyalah permulaan. Jika Anda ingin mempelajari analisis performa lebih dalam, langkah mudah berikutnya adalah melacak lebih banyak metrik.
Dalam lab kode ini, Anda melacak metrik yang terkait dengan kapan resource tersedia untuk pengguna. Jika mau, Anda dapat menguraikan sebagian besar kategori ini lebih lanjut. Misalnya, alih-alih hanya mengukur kapan JavaScript selesai dieksekusi, Anda dapat mengukur kapan JavaScript mulai dimuat, kapan JavaScript selesai dimuat, kapan JavaScript mulai dieksekusi, dan akhirnya kapan JavaScript selesai dieksekusi. Setiap metrik ini dapat mengungkap masalah yang mungkin tidak dapat diungkapkan oleh salah satu metrik saja.
Selain mendapatkan data yang lebih terperinci, Anda juga harus berpikir lebih menyeluruh tentang strategi analisis performa umum. Apa saja sasarannya? Apa itu kesuksesan?
Untuk semua jenis analisis, Anda biasanya ingin memulai dengan mengajukan pertanyaan, lalu mencari tahu cara menggunakan data untuk menjawab pertanyaan tersebut.
Misalnya, pertimbangkan daftar pertanyaan berikut, dan cara Anda menggunakan pengetahuan yang diperoleh dalam codelab ini untuk menggunakan analisis guna menjawabnya:
- Apakah nilai metrik yang Anda lacak menurun atau meningkat dari waktu ke waktu?
- Bagaimana penggunaan penyimpanan offline melalui pekerja layanan atau penyimpanan lokal memengaruhi performa keseluruhan situs Anda?
- Apakah resource Anda dimuat secara optimal? Artinya, apakah ada jeda yang besar antara saat resource didownload dan saat resource tersedia untuk digunakan?
- Apakah ada korelasi antara performa dan metrik lain yang Anda lacak (misalnya, rasio pendaftaran, waktu di situs, pembelian, dll.)?
Terakhir, jika Anda ingin mempelajari lebih lanjut performa web atau Google Analytics, berikut beberapa referensi bagus untuk memulai:
- Alat dan informasi untuk membantu Anda membuat situs web berperforma tinggi
https://developers.google.com/speed/ - Alat dan API bagi developer untuk memanfaatkan platform Google Analytics
https://developers.google.com/analytics/ - Kursus online yang mengajarkan cara menggunakan produk Google Analytics itu sendiri (diajarkan oleh orang-orang yang bekerja di Google Analytics itu sendiri.
https://analyticsacademy.withgoogle.com/