In questo codelab, imparerai a utilizzare Google Analytics e l'API User Timings per misurare le prestazioni reali del tuo sito web o della tua applicazione e di ottimizzarle per migliorare l'esperienza dei tuoi utenti.
Strumenti come WebPagetest.org sono un ottimo punto di partenza per l'ottimizzazione del rendimento, ma il vero test delle prestazioni del sito consiste sempre nel fornire dati reali degli utenti effettivi.
Se gestisci un sito web, esiste già una buona probabilità che tu stia già utilizzando Google Analytics per misurare il traffico, ma anche per l'utilizzo dei dispositivi e dei browser. Con un piccolo codice aggiuntivo puoi aggiungere metriche sul rendimento al mix.
Obiettivi didattici
- Come misurare in modo preciso ed efficace le metriche sul rendimento utilizzando l'API User Timings
- Come inviare questi dati a Google Analytics in modo da poterli incorporare nei report
Che cosa ti serve
- Un browser con una console per sviluppatori
- Web Server per Chrome oppure utilizza il tuo server web preferito
- Il codice campione
- Un editor di testo
- (Facoltativo) Un account Google Analytics
Come utilizzerai questo tutorial?
Come giudichi la tua esperienza con la creazione di siti web o applicazioni?
Puoi scaricare tutto il codice di esempio sul computer...
...o clona il repository GitHub dalla riga di comando.
git clone https://github.com/googlecodelabs/performance-analytics.git
Il codice di esempio è diviso in sottodirectory che corrispondono a ciascuno dei passaggi numerati di questo codelab. Puoi utilizzarla per saltare facilmente il codelab o per verificare che l'implementazione sia corretta.
Se hai accesso a un programma di distribuzione, puoi utilizzarlo per vedere esattamente cosa è cambiato da un passaggio all'altro.
In questo codelab, acquisirai un unico file HTML che carica i seguenti asset:
- Caratteri web
- Fogli di stile
- Immagini
- JavaScript
Dovrai scrivere un nuovo codice che misuri le metriche chiave sul rendimento di ciascuno di questi tipi di asset.
Considerazioni sul rendimento degli asset
Se hai letto qualcosa sull'ottimizzazione del rendimento, probabilmente sai già che ciascuno di questi tipi di asset presenta delle peculiarità e può influenzare il rendimento complessivo percepito in vari modi.
CSS
Ad esempio, i fogli di stile bloccano il rendering di tutti gli elementi del DOM che li seguono, il che significa che il browser deve effettuare una richiesta di foglio di stile, scaricarlo e analizzarlo prima di poter visualizzare qualsiasi contenuto del DOM successivo. Per questo motivo, è solitamente preferibile posizionare i fogli di stile nella &&head;test> del documento. Inoltre, a causa della natura di blocco degli SSC, spesso è consigliato inserire solo il codice CSS critico in <head> e in un secondo momento carica il codice CSS non critico.
JavaScript
JavaScript, invece, non blocca il rendering, ma blocca l'analisi e la creazione del DOM. Questa operazione è necessaria perché JavaScript può modificare il DOM, ovvero ogni volta che il browser vede un tag <script> (esclusi gli script asincroni), deve eseguire il codice prima di passare al tag successivo. Se il tag <script> fa riferimento a un file JavaScript esterno, deve scaricare ed eseguire il codice prima di procedere.
Per questo motivo spesso consigliamo di caricare il codice JavaScript subito prima del tag di chiusura &body>, in modo che la maggior parte del DOM sia disponibile il più rapidamente possibile.
Caratteri web
Se carichi i caratteri web, potresti anche scegliere di bloccare il rendering del documento finché il carattere non è disponibile per essere utilizzato. In questo caso, è fondamentale capire quanto tempo occorre ai tuoi utenti. È possibile che un carattere web venga caricato velocemente, ma molto lentamente per la maggior parte degli utenti che lo visita. È per questo che la misurazione e la decisione su dati reali sono così importanti.
Immagini
Infine, le immagini possono davvero animare un sito, ma spesso possono anche richiedere più tempo. Comprendere cosa significa effettivamente ed essere in grado di individuare eventuali correlazioni tra pattern di utilizzo e tempi di caricamento della pagina è fondamentale per capire come ottimizzare la campagna.
Il primo passaggio in questo codelab consiste nel verificare l'aspetto della pagina demo prima di aggiungere qualsiasi codice di misurazione del rendimento.
Per visualizzare la demo, crea una nuova cartella e aggiungi al suo interno un file denominato index.html. Quindi, copia e incolla il codice seguente nel 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>
Successivamente, apri Web Server per Chrome e avvia un server locale nella directory appena creata. Assicurati che la casella di controllo " mostra automaticamente index.html".
Ora dovresti essere in grado di aprire http://127.0.0.1:8887/ nel browser e visualizzare il file demo. Il sito dovrebbe avere il seguente aspetto:
Una volta che la pagina demo è in esecuzione, prenditi un momento per dare un'occhiata al codice e vedere tutti i vari tipi di asset caricati. Nei prossimi passaggi aggiungerai codice per misurare quando questi asset vengono caricati e possono essere interagito con l'utente.
Come indicato in precedenza nella sezione relativa alle considerazioni sul rendimento degli asset, il CSS blocca il rendering degli elementi DOM, nonché l'esecuzione di script successivi al DOM.
Il file demo appena creato contiene il seguente CSS, che fa riferimento al Bootstrap e ad alcuni stili incorporati.
<!-- 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 -->
Poiché il CSS blocca sia il rendering degli elementi DOM sia l'esecuzione di script, è possibile determinare quando il CSS ha finito di bloccare aggiungendo un tag <script>
immediatamente dopo il CSS in cui è memorizzata l'ora attuale.
Puoi farlo creando una variabile e assegnandovi new Date()
, ma grazie all'API User Timings, esiste un modo molto più semplice: il metodo performance.mark
.
Per contrassegnare quando il CSS ha bloccato sia il rendering sia l'esecuzione dello script, aggiungi la seguente riga di codice immediatamente prima del commento di <!-- End CSS -->
di chiusura.
<script>performance.mark('css:unblock');</script>
Il metodo performance.mark
crea un timestamp ad alta risoluzione in questo momento esatto e lo associa a qualsiasi nome trasmesso al metodo. In questo caso hai chiamato il segno "quot;css:unblock".
Il metodo performance.mark
va di pari passo con il metodo performance.measure
, che viene utilizzato per calcolare la differenza di tempo tra due indicatori (oltre a quelli segnati da te, puoi anche utilizzare quelli segnati automaticamente dal browser per i vari punti nell'API Navigation Timing).
La seguente funzione di utilità misura e restituisce la durata tra un contrassegno che hai aggiunto e il segno responseEnd creato dall'API Navigation Timing.
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;
}
Per iniziare a utilizzare questa funzione di utilità, crea un nuovo file denominato perf-analytics.js
(nella stessa directory del file index.html
) e copia al suo interno il codice riportato sopra.
Ora che questa funzione è stata definita, puoi chiamarla e passare il nome del marchio "css:unblock". Per non interferire con il caricamento di altre risorse, dovresti rimandare l'esecuzione di queste misurazioni fino all'attivazione dell'evento di caricamento della finestra.
Dopo aver scritto una funzione per chiamare questo codice, il file perf-analytics.js
dovrebbe essere simile al seguente:
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;
}
Infine, devi caricare lo script perf-analytics.js
da index.html
. A tale scopo, aggiungi il seguente tag script al documento principale. Assicurati di aggiungerlo per ultimo, in modo che non interferisca con il caricamento di altre risorse.
<!-- Start performance analytics -->
<script async src="perf-analytics.js"></script>
<!-- End performance analytics -->
Una volta completato questo passaggio, il codice dovrebbe corrispondere a quello presente nella directory 01-css
del repository del codelab.
Se carichi la pagina in un browser e apri la Developer Console, dovresti vedere un output simile al seguente:
In genere, i caratteri web vengono caricati tramite un foglio di stile esterno, come puoi vedere nel file demo iniziale:
<!-- Start fonts -->
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700,400italic" rel="stylesheet">
<!-- End fonts -->
Dato che si tratta di un tag <link>
in un file CSS, potrebbe sembrare che il caricamento dei caratteri e dell'utilizzo siano semplici come aggiungere un contrassegno all'interno di un tag <script>
subito dopo l'elemento <link>
, come nel passaggio 1.
Purtroppo non è così semplice.
I fogli di stile bloccano l'esecuzione di JavaScript perché i contenuti dei fogli di stile vengono utilizzati per creare CSSOM e, poiché è possibile che JavaScript venga caricato, deve accedere al CSSOM, l'esecuzione deve essere ritardata fino alla completa creazione del CSSOM.
Il problema è che il browser può creare il CSSOM senza scaricare effettivamente il carattere. Ciò significa che se aggiungi un contrassegno tramite un tag script incorporato al DOM subito dopo il foglio di stile del carattere <link>, è probabile che il segno si verifichi prima del caricamento completo del carattere.
Finché gli eventi di caricamento dei caratteri non diventano disponibili nei browser, JavaScript è necessario per determinare quando un carattere è effettivamente attivo e pronto per l'utilizzo nella pagina. Fortunatamente, il caricamento di caratteri tramite JavaScript comporta anche risultati positivi, dal momento che non richiede una richiesta di blocco aggiuntiva a un file CSS.
La maggior parte dei caratteri web (inclusi i caratteri Google, typekit e font.com) possono essere caricati tramite lo script webfont.js, sviluppato in collaborazione da Google e Typekit.
Per aggiornare il documento principale in modo da utilizzare webfont.js per caricare i caratteri (anziché il tag <link>), sostituisci la sezione dei caratteri del codice con quanto segue:
<!-- 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 -->
Il codice riportato sopra è importante per due aspetti:
- Crea un contrassegno "fonts:active" nel callback attivo, per consentirti di misurare in un secondo momento il tempo necessario per il caricamento dei caratteri.
- Il tag
<script>
che carica webfonts.js contiene l'attributoasync
, pertanto non blocca l'analisi o il rendering del resto del documento (questo non è vero per i tag<link>
).
I codici sopra riportati creano l'indicatore "fonts:active" e misurare questo marchio e registrarlo nella console non è un'operazione così semplice come prima. Il motivo per cui il caricamento del carattere ora avviene in modo asincrono, quindi se provi a misurare il carattere "fonts:active" nel gestore window.onload
(come hai fatto con "css:unblock"), è molto possibile che il carattere non venga ancora caricato.
Per risolvere il problema, puoi creare una promessa che viene risolta una volta caricato il carattere. Questa è la funzione che segue. Copialo e incollalo nel 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')
});
}
Aggiorna anche il gestore window.onload
per chiamare questa nuova funzione
window.onload = function() {
measureCssUnblockTime();
measureWebfontPerfAndFailures();
};
Una volta completato questo passaggio, il codice dovrebbe corrispondere a quello presente nella directory 02-fonts
del repository del codelab.
Se carichi la pagina in un browser e apri la Developer Console, dovresti vedere un output simile al seguente:
Sapere quando un'immagine è visibile non è così semplice come potrebbe apparire. Nei passaggi precedenti, i fogli di stile e i tag <script>
sincroni possono bloccare il rendering, l'analisi e l'esecuzione degli script. Potresti non sapere che nessuno di loro blocca lo scanner di precaricamento del browser.
Uno scanner di precaricamento è un'implementazione di tutto il browser moderno che costituisce uno dei tanti tentativi di migliorare le prestazioni, anche sui siti non dediti al marketing che contengono molte risorse di blocco. L'idea è che, nonostante alcuni asset possano bloccare l'analisi, il rendering o l'esecuzione dello script, non è necessario bloccare i download. Il browser esegue la scansione del file HTML prima di iniziare a creare il DOM e cerca gli asset da cui è possibile iniziare il download immediatamente.
Per quanto riguarda le immagini, ciò significa che esiste una buona probabilità che le tue immagini possano essere già scaricate prima di essere aggiunte al DOM. Ciò significa anche che il punto in cui un'immagine viene scaricata non è necessariamente una buona metrica di rendimento. La metrica relativa alle prestazioni che ti interessa è il punto in cui un'immagine è visibile all'utente.
Quando un'immagine viene scaricata prima di essere aggiunta al DOM, il punto in cui diventa visibile è il punto in cui si trova nel DOM. D'altra parte, se un'immagine non viene scaricata prima di essere aggiunta al DOM, il punto in cui diventa visibile è quando viene attivato il gestore di onload
.
Pertanto, per sapere quando un'immagine è visibile, devi gestire entrambi i casi.
A tale scopo, aggiungi i simboli nel gestore di caricamento di ogni immagine e in un tag <script> in linea subito dopo l'ultima immagine nel DOM. L'idea è che il segno che si verifica per ultimo sarà quello che rappresenta quando tutte le immagini sono visibili.
Per aggiungere indicatori sia al caricamento delle immagini che al rendering dell'immagine, aggiorna il codice dell'immagine in index.html
come segue:
<!-- 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 -->
Poiché il metodo performance.measure
per un determinato nome di marchio utilizzerà sempre l'ultimo marchio (se trova più marchi con lo stesso nome), per questa operazione puoi utilizzare la funzione di utilità measureDuration
nel file perf-analytics.js
senza alcuna modifica aggiuntiva:
/**
* 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'));
}
Aggiungi la funzione riportata sopra al file perf-analytics.js
, quindi aggiorna il gestore window.onload
per chiamarla:
window.onload = function() {
measureCssBlockTime();
measureWebfontPerfAndFailures();
measureImagesVisibleTime();
};
Una volta completato questo passaggio, il codice dovrebbe corrispondere a quello presente nella directory 03-images
del repository del codelab.
Se carichi la pagina in un browser e apri la Developer Console, dovresti vedere un output simile al seguente:
Poiché i tag <script>
senza l'attributo async
bloccano l'analisi DOM fino al download e all'esecuzione, puoi stabilire il punto in cui tutti gli script hanno terminato l'esecuzione aggiungendo un contrassegno in un tag script in linea immediatamente dopo l'ultimo <script>
sincrono nel DOM.
Tieni presente che l'utilizzo di gestori onload
non funziona in questo caso, in quanto il browser deve eseguire lo script dopo il suo caricamento e questa operazione richiede tempo. Uno script che si carica velocemente, ma che può essere eseguito lentamente, può essere pericoloso.
Per tenere traccia di quando tutto il codice JavaScript viene caricato ed eseguito nel documento principale, aggiorna la sezione JavaScript in index.html
con il seguente codice:
<!-- 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 -->
Verrà aggiunto un contrassegno denominato "js:execute" subito dopo aver scaricato gli script per i plug-in jQuery e Bootstrap.
Per misurare il tempo necessario, aggiungi la seguente funzione a 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'));
}
Successivamente, richiamala dal gestore window.onload
:
window.onload = function() {
measureCssBlockTime();
measureWebfontPerfAndFailures();
measureImagesVisibleTime();
measureJavaSciptExecutionTime();
};
Una volta completato questo passaggio, il codice dovrebbe corrispondere a quello presente nella directory 04-javascript
del repository del codelab.
Se carichi la pagina in un browser e apri la Developer Console, dovresti vedere un output simile al seguente:
Non tutti i browser supportano le promesse JavaScript o le API User Timing. Se esegui il codice scritto finora in un browser senza supporto per una di queste funzionalità, verranno visualizzati errori.
Per farlo, puoi usare il rilevamento delle funzionalità. Aggiungi il seguente snippet di codice immediatamente prima della sezione dei caratteri. Questa riga di JavaScript rileva il supporto per il metodo performance.mark
, pertanto deve essere aggiunta alla pagina prima che venga utilizzato il metodo:
<!-- Start feature detects -->
<script>window.__perf = window.performance && performance.mark;</script>
<!-- End feature detects -->
Poi, in qualsiasi punto di index.html
dove chiami performance.mark
, aggiungi il prefisso di rilevamento della funzionalità. Ecco un esempio che aggiorna il codice nel blocco di immagini, ma devi assicurarti di aggiornare anche le altre sezioni.
<!-- 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 -->
Ora che la variabile __perf
è impostata su window
, puoi utilizzarla anche in perf-analytics.js
per assicurarti di non chiamare un metodo che non è supportato nel browser corrente.
La funzione measureDuration
deve essere aggiornata per aggiungere la seguente condizione:
function measureDuration(mark, opt_reference) {
if (window.__perf) {
// ...
}
}
Infine, poiché non tutti i browser supportano le promesse JavaScript, anche la funzione measureWebfontPerfAndFailures
deve essere aggregata in una condizione condizionale:
function measureWebfontPerfAndFailures() {
if (window.Promise) {
// ...
}
}
Ora dovresti essere in grado di eseguire il codice in qualsiasi browser senza problemi.
Una volta completato questo passaggio, il codice dovrebbe corrispondere a quello presente nella directory 05-feature-detects
del repository del codelab.
L'ultimo passaggio di questo codelab consiste nel trasferire i dati registrati nella console e inviarli invece a Google Analytics. Prima di inviare i dati a Google Analytics, devi aggiungere la libreria analytics.js e lo snippet di monitoraggio predefinito alla tua pagina.
Aggiungi il seguente codice a index.html
dopo il blocco JavaScript principale, ma prima del caricamento dello script perf-analytics.js
:
<!-- 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 -->
Se hai già aggiunto Google Analytics a un sito web, significa che devi sostituire il segnaposto "UA-XXXXX-Y" con l'ID monitoraggio che hai ricevuto durante la creazione di una nuova proprietà in Google Analytics.
Lo snippet di monitoraggio di analytics.js esegue quattro operazioni principali:
- Crea un elemento
<script>
asincrono che scarica la libreria JavaScript analytics.js. - Inizializza una funzione
ga()
globale (chiamata coda di comandi ga()) che consente di pianificare l'esecuzione dei comandi quando la libreria analytics.js è caricata e pronta per l'uso. - Aggiunge un comando alla coda di comandi
ga()
per creare un nuovo oggetto tracker per la proprietà specificata tramite il parametro'UA-XXXXX-Y'. - Aggiunge un altro comando alla coda di comandi
ga()
per inviare una visualizzazione di pagina a Google Analytics per la pagina corrente.
I dati raccolti dalle sole visualizzazioni di pagina sono utili, ma non forniscono una visione completa. Per avere un quadro migliore dell'esperienza degli utenti sul tuo sito o sulla tua applicazione, devi inviare dati aggiuntivi sulle interazioni a Google Analytics.
Google Analytics supporta diversi tipi di dati sulle interazioni: visualizzazioni di pagina, eventi, interazioni social, eccezioni e (ultimo ma non meno importante) tempi degli utenti. Per inviare dati relativi ai tempi utente a Google Analytics, puoi utilizzare la seguente firma di comando:
ga('send', 'timing', timingCategory, timingVar, timingValue);
Dove timingCategory
è una stringa che ti consente di organizzare gli hit tempi in un gruppo logico, timingVar
è la variabile che stai misurando e timingValue
è la durata effettiva in millisecondi.
Per vedere come funziona in pratica, l'istruzione console.log
nella funzione measureCssUnblockTime
può essere aggiornata come segue:
ga('send', 'timing', 'CSS', 'unblock', measureDuration('css:unblock'));
Sebbene il codice riportato sopra funzioni in alcune situazioni, ci sono due aspetti importanti da tenere presenti:
- Il passaggio precedente ha aggiornato la funzione
measureDuration
in modo che venga eseguita solo se il browser supporta l'API User Timings, che a volte restituisceundefined
. Poiché non esiste alcun motivo per l'invio di dati non definiti a Google Analytics (in alcuni casi potrebbe persino creare problemi nei report), devi inviare questo hit temporaneo solo semeasureDuration
restituisce un valore. - Quando
measureDuration
restituisce un valore, si tratta di unDOMHighResTimeStamp
, che avrà una precisione superiore a un millisecondo. PoichétimingValue
in Google Analytics deve essere un numero intero, devi arrotondare il valore restituito dameasureDuration
.
Per prendere in considerazione questi reso, aggiorna l'istruzione di ritorno nella funzione measurementDuration per arrotondare il valore restituito:
function measureDuration(mark, opt_reference) {
if (window.__perf) {
// ...
return Math.round(measure.duration);
}
}
Inoltre, aggiorna i comandi di tempo da eseguire solo se esiste un valore per la metrica in questione. Ad esempio, la funzione measureCssUnblockTime
deve essere aggiornata in modo simile al seguente:
function measureCssUnblockTime() {
var cssUnblockTime = measureDuration('css:unblock');
if (cssUnblockTime) {
ga('send', 'timing', 'CSS', 'unblock', cssUnblockTime);
}
}
Dovrai apportare aggiornamenti simili a tutte le altre funzioni di misurazione. Al termine, il file perf-analytics.js finale dovrebbe avere il seguente aspetto:
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);
}
}
Il file index.html finale dovrebbe avere questo aspetto:
<!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>
Se carichi questa pagina e dai un'occhiata alle richieste nel riquadro di rete, vedrai quanto segue:
Questa procedura è utile, ma potrebbe essere complicato consultare questi dati come richiesta con codifica URL. E, se per qualche motivo non vedi queste richieste, è molto difficile individuare dove si è verificato l'errore.
Un approccio migliore durante lo sviluppo in locale è utilizzare la versione di debug di analytics.js, che registra informazioni di debug utili nella console man mano che viene eseguito ogni comando analytics.js. Se
aggiorna l'URL analytics.js in index.html
a analytics_debug.js
e apri la console del browser, vedrai le istruzioni stampate in questo modo:
Ora che hai compreso come implementare la misurazione del rendimento per questa pagina demo, puoi provare ad aggiungerla al tuo sito inviando dati utente reali a Google Analytics.
Report sui dati raccolti
Dopo aver raccolto dati sul rendimento per alcuni giorni, potrai generare rapporti su tali dati per acquisire informazioni strategiche sulla velocità di caricamento del tuo sito e delle sue risorse per utenti reali.
Per accedere ai report Tempi utente in Google Analytics, fai clic sulla scheda Report in alto e seleziona"Comportamento"e"Velocità sito".
Quando carichi il rapporto Tempi utente in Google Analytics, dovresti essere in grado di visualizzare le categorie di tempo corrispondenti ai dati che hai inviato. Fai clic su uno di questi per vedere visualizzazioni dettagliate dei tuoi dati temporali. L'immagine seguente è un esempio di tempi di caricamento del carattere su un sito web reale utilizzando Google Fonts nelle ultime 24 ore.
Complimenti! Hai completato questo lab di codice. Se desideri informazioni più approfondite, nella sezione successiva troverai alcuni suggerimenti su come basarti su questo codice per ottenere ancora più informazioni approfondite.
Le metriche sul rendimento trattate in questo codelab sono fondamentali per misurare il caricamento del tuo sito per utenti reali, ma sono solo l'inizio. Se vuoi approfondire l'analisi del rendimento, un passo successivo è quello di monitorare più metriche.
In questo lab, hai monitorato le metriche relative alla disponibilità delle risorse per l'utente. Se lo desideri, puoi suddividere ulteriormente la maggior parte di questi elementi. Ad esempio, anziché misurare semplicemente il termine dell'esecuzione di JavaScript, puoi misurare quando ha iniziato e finito l'esecuzione e infine l'esecuzione. Ognuna di queste metriche potrebbe rivelare un problema che solo una di esse potrebbe non identificare.
Oltre a diventare più granulare, dovresti pensare anche più dettagliatamente alla tua strategia generale di analisi del rendimento. Quali sono gli obiettivi? Che cos'è un successo?
Per quanto riguarda i tipi di dati analitici, di solito è necessario iniziare con una domanda specifica per poi capire come utilizzare i dati per rispondere.
Ad esempio, considera il seguente elenco di domande e come useresti le conoscenze acquisite in questo codelab per utilizzare Analytics per rispondere:
- I valori delle metriche di cui il monitoraggio monitora una diminuzione o un aumento nel tempo?
- In che modo l'utilizzo della memorizzazione nella cache offline tramite service worker o archiviazione locale influisce sulle prestazioni complessive del sito?
- Le tue risorse vengono caricate in modo ottimale? C'è un grande divario tra il momento in cui la risorsa viene scaricata e quella in cui è disponibile per l'utilizzo?
- Ci sono correlazioni tra il rendimento e altre metriche monitorate (ad es.percentuale di iscrizione, tempo sul sito, acquisti ecc.)?
Infine, se desideri saperne di più sulle prestazioni web o su Google Analytics, ecco alcune risorse utili per iniziare:
- Strumenti e informazioni per creare siti web ad alte prestazioni
https://developers.google.com/speed/ - Strumenti e API per consentire agli sviluppatori di sfruttare la piattaforma di Google Analytics
https://developers.google.com/analytics/ - Corsi online che ti insegnano a utilizzare il prodotto Google Analytics (insegnato da persone che lavorano direttamente su Google Analytics).
https://analyticsacademy.withgoogle.com/