Tiempos del usuario: Seguimiento web (ga.js)

En este documento, se proporciona una guía completa sobre el uso del método _trackTiming.

Introducción

Hay estudios que demuestran que reducir el tiempo que tarda una página en cargarse mejora la experiencia general del usuario de un sitio. Google Analytics cuenta con una serie de informes eficaces que realizan un seguimiento automático del tiempo de carga de las páginas. Pero ¿qué sucede si deseas hacer un seguimiento del tiempo que tarda un recurso en particular en cargarse?

Por ejemplo, ¿lleva demasiado tiempo cargar una biblioteca JavaScript popular y esto disminuye la experiencia del sitio para ciertos usuarios?

Los tiempos del usuario te permiten responder esta pregunta, ya que proporcionan una forma nativa de realizar un seguimiento de un período en Google Analytics.

Para ver un ejemplo de funcionamiento, consulta el código de muestra de Tiempos de usuario.

Cómo configurar los tiempos de usuario

Para recopilar datos de tiempo del usuario, usa el método _trackTiming, que envía datos de tiempo a Google Analytics.

_gaq.push([‘_trackTiming’, category, variable, time, opt_label, opt_sample]);

En el que los parámetros representan lo siguiente:

Parámetro Valor Obligatorio Resumen
category string Es una cadena para categorizar todas las variables de tiempo del usuario en grupos lógicos para facilitar la generación de informes. Por ejemplo, puedes usar el valor de jQuery si realizas un seguimiento del tiempo que tardó en cargar esa biblioteca JavaScript en particular.
variable string Es una cadena para indicar el nombre de la acción del recurso del que se hace un seguimiento. Por ejemplo, podrías usar el valor de JavaScript Load si quisieras hacer un seguimiento del tiempo que tardó en cargar la biblioteca JavaScript de jQuery. Ten en cuenta que se pueden usar las mismas variables en varias categorías para hacer un seguimiento de los tiempos de un evento común a esas categorías, como Javascript Load y Page Ready Time, etcétera.
time number Es la cantidad de milisegundos que transcurren en el tiempo transcurrido para informar a Google Analytics. Si la biblioteca de jQuery tardó 20 milisegundos en cargarse, deberías enviar el valor de 20.
opt_label string no Es una cadena que se puede usar para agregar flexibilidad a la hora de visualizar los tiempos de los usuarios en los informes. Las etiquetas también se pueden usar a fin de enfocarse en diferentes subexperimentos para la misma combinación de categoría y variable. Por ejemplo, si cargamos jQuery desde la red de distribución de contenidos de Google, usaríamos el valor de Google CDN.
opt_sampleRate number no Es un número para anular manualmente el porcentaje de visitantes cuyos hits de tiempo se envían a Google Analytics. El valor predeterminado es el mismo que la recopilación de datos de velocidad general del sitio y se basa en un porcentaje de visitantes. Por lo tanto, si quisieras hacer un seguimiento de los hits de _trackTiming para el 100% de los visitantes, deberías usar el valor 100. Ten en cuenta que cada hit se considera para el límite general de 500 hits por sesión.

Volver al principio

Tiempo de seguimiento utilizado

Cuando usas el método _trackTiming, debes especificar la cantidad de milisegundos dedicados al parámetro time. Por lo tanto, depende de ti, el desarrollador, escribir código para capturar este período. La manera más fácil de hacerlo es crear una marca de tiempo al comienzo de un período y crear otra marca de tiempo al final de este. Luego, puedes hacer la diferencia entre ambas marcas de tiempo para calcular el tiempo.

Este es un ejemplo simple:

var startTime = new Date().getTime();

setTimeout(myCallback, 200);

function myCallback(event) {

  var endTime = new Date().getTime();
  var timeSpent = endTime - startTime;

  _gaq.push(['_trackTiming', 'Test', 'callback_timeout', timeSpent, 'animation']);
}

Para recuperar la marca de tiempo de inicio, se crea un nuevo objeto Date y se obtiene la hora en milisegundos. Luego, se usa la función setTimeout para llamar a la función myCallback en 200 milisegundos. Una vez que se ejecuta la función de devolución de llamada, se recupera la marca de tiempo endTime creando un nuevo objeto Date. Luego, se calcula la diferencia entre las horas de inicio y finalización para obtener el tiempo empleado. Por último, el tiempo dedicado se envía a Google Analytics.

Este ejemplo es insignificante, pero ilustra el concepto de cómo hacer un seguimiento del tiempo. Veamos un ejemplo más realista.

Volver al principio

Cómo realizar un seguimiento del tiempo dedicado a cargar un recurso JavaScript

Hoy en día, muchos sitios incluyen bibliotecas de JavaScript de terceros o solicitan datos a través de objetos JSON. Si bien es posible que tu sitio cargue estos recursos rápidamente en casa, es posible que los mismos recursos se carguen muy lento para los usuarios de otros países. Estos recursos de carga lenta pueden degradar la experiencia del sitio para los usuarios internacionales.

La función de tiempo del usuario para la velocidad del sitio puede ayudarte a recopilar y a informar cuánto tardan en cargarse estos recursos.

A continuación, se incluye un ejemplo simple que muestra cómo hacer un seguimiento del tiempo dedicado a una función que carga recursos JavaScript de manera asíncrona:

var startTime;

function loadJs(url, callback) {
  var js = document.createElement('script');
  js.async = true;
  js.src = url;
  var s = document.getElementsByTagName('script')[0];

  js.onload = callback;
  startTime = new Date().getTime();

  s.parentNode.insertBefore(js, s);
}

function myCallback(event) {
  var endTime = new Date().getTime();
  var timeSpent = endTime - startTime;
  _gaq.push(['_trackTiming', 'jQuery', 'Load Library', timeSpent, 'Google CDN']);

  // Library has loaded. Now you can use it.
};

Ten en cuenta que este ejemplo es muy similar al anterior.

En este ejemplo, loadJs es una función de utilidad que carga recursos de JavaScript creando de forma dinámica un elemento de secuencia de comandos y adjuntándolo al DOM del navegador. La función acepta dos parámetros: una URL como cadena y una función de devolución de llamada que se ejecutará una vez que se cargue la secuencia de comandos.

Dentro de loadJs, una marca de tiempo de inicio se almacena en startTime. Una vez que se carga el recurso, se ejecuta la función de devolución de llamada. En la función de devolución de llamada, se recupera la marca de tiempo de finalización y se usa para calcular el tiempo que se tardó en cargar el recurso JavaScript. Este tiempo se envía a Google Analytics con el método _trackTiming.

Entonces, si llamas:

loadJs(‘//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js’, callback);

Carga la biblioteca jQuery de manera asíncrona desde la red de distribución de contenidos de Google y, una vez completada, ejecuta la función de devolución de llamada que, a su vez, envía el tiempo de carga del recurso a Google Analytics.

Volver al principio

Cómo trabajar con varios tiempos de usuario

Supongamos que deseas cargar varios recursos de JavaScript con el código anterior. Como la variable startTime es global, cada vez que realices un seguimiento del inicio de un período, se reemplazará la variable startTime, lo que generará un tiempo incorrecto.

Por lo tanto, como práctica recomendada, debes mantener una instancia única de la hora de inicio y finalización para cada recurso del que quieras hacer un seguimiento.

Además, observa que los parámetros de categoría y variable de _trackTiming están codificados. Por lo tanto, si usas loadJs para cargar varios recursos, no podrás distinguir cada uno de ellos en los informes de Google Analytics.

Ambos problemas se pueden resolver almacenando los parámetros de tiempo y _trackTiming en un objeto JavaScript.

Crear un objeto JavaScript para almacenar los tiempos de los usuarios

A continuación, se muestra un objeto JavaScript simple que puede usarse para almacenar los datos de sincronización del usuario para cada recurso del que se hace un seguimiento:

function TrackTiming(category, variable, opt_label) {
  this.category = category;
  this.variable = variable;
  this.label = opt_label ? opt_label : undefined;
  this.startTime;
  this.endTime;
  return this;
}

TrackTiming.prototype.startTime = function() {
  this.startTime = new Date().getTime();
  return this;
}

TrackTiming.prototype.endTime = function() {
  this.endTime = new Date().getTime();
  return this;
}

TrackTiming.prototype.send = function() {
  var timeSpent = this.endTime - this.startTime;
  window._gaq.push(['_trackTiming', this.category, this.variable, timeSpent, this.label]);
  return this;
}

Ahora podemos usar este objeto para hacer que loadJs funcione para varias solicitudes.

Cómo enviar tiempos del usuario almacenados

Ahora que tenemos una manera de almacenar datos de tiempo para cada recurso del que queremos hacer un seguimiento, a continuación se muestra cómo actualizar loadJs para usarlo:

var tt = new TrackTiming('jQuery', 'Load Library', 'Google CDN');

loadJs(‘//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js’, myCallback, tt);

function loadJs(url, callback, tt) {
  var js = document.createElement('script');
  js.async = true;
  js.src = url;
  js.onload = callback;
  var s = document.getElementsByTagName('script')[0];

  tt.startTime();
  js.tt = tt;

  s.parentNode.insertBefore(js, s);
}

function myCallback(event) {
  var e = event || window.event;
  var target = e.target ? e.target : e.srcElement;

  target.tt.endTime().send();

  // Library has loaded. Now you can use it.
}

El código anterior comienza con la creación de un nuevo objeto TrackTiming en el que la categoría, la variable y la etiqueta opcional se pasan al constructor. Luego, el objeto TrackTiming se pasa como parámetro a la función loadJs.

Dentro de loadJs, se llama al método startTime para obtener y almacenar la marca de tiempo de inicio.

En el ejemplo anterior, la función de devolución de llamada podía acceder fácilmente a la variable startTime porque era global. Ahora que startTime es parte del objeto TrackTiming, necesitamos una manera de pasar este objeto desde la función loadJs a la función de devolución de llamada.

Para resolver este problema, una estrategia es agregar el objeto TrackTiming como una propiedad al elemento de la secuencia de comandos. Dado que la función de devolución de llamada se ejecuta desde el método onload de la secuencia de comandos, la devolución de llamada recibe un objeto de evento como parámetro. Este objeto de evento se puede usar para recuperar el objeto de secuencia de comandos original que activó el evento y, a su vez, se puede usar para acceder a nuestro objeto TrackTiming.

Una vez que podamos acceder a nuestro objeto TrackTiming original, la secuencia de comandos podrá finalizar la hora y enviar los datos.

Consulta una demostración en vivo de este ejemplo en nuestro sitio de muestras.

Este patrón de agregar el objeto TrackTiming como una propiedad al objeto del que se hace seguimiento suele funcionar bien para hacer un seguimiento de otros mecanismos de carga asíncrona, como el uso del objeto XMLHttpRequest.

Volver al principio

Seguimiento de XMLHttpRequests

Otra forma común de cargar de forma asíncrona los recursos de la página web es usar el objeto XMLHttpRequest. También se puede hacer un seguimiento del tiempo que se tarda en cargar estos recursos con el método _trackTiming y el objeto TimeTracker.

Este es un ejemplo que carga el archivo de cotizaciones del servidor.

var url = ‘//myhost.com/quotes.txt’;
var tt = new TrackTime('xhr demo', 'load quotes');

makeXhrRequest(url, myCallback, tt);

function makeXhrRequest(url, callback, tt) {
  if (window.XMLHttpRequest) {
    var xhr = new window.XMLHttpRequest;
    xhr.open('GET', url, true);
    xhr.onreadystatechange = callback;

    tt.startTime();
    xhr.tt = tt;

    xhr.send();
  }
}

function myCallback(event) {
  var e = event || window.event;
  var target = e.target ? e.target : e.srcElement;

  if (target.readyState == 4) {
    if (target.status == 200) {

      target.tt.endTime().send();

      // Do something with the resource.
    }
  }
}

Este ejemplo es muy similar al ejemplo de loadJs. Mira la demostración en vivo aquí.

Volver al principio

Evita el envío de datos con errores

En los ejemplos anteriores, para conocer el tiempo invertido, el código resta la hora de finalización de la hora de inicio. Por lo general, funciona bien, siempre y cuando la hora de inicio sea anterior a la hora de finalización. Sin embargo, puede convertirse en un problema si cambia la hora en el navegador. Si el usuario cambia la hora de la máquina después de establecer la hora de inicio, se pueden enviar datos incorrectos a Google Analytics. Un gran problema cuando se envía un gran valor incorrecto es que sesgará las métricas promedio y total.

Por lo tanto, la práctica recomendada es asegurarte de que el tiempo invertido sea mayor que 0 y menor que un período determinado, antes de enviar los datos a Google Analytics. Podemos modificar el método de envío TimeTracker anterior para realizar esta verificación:

TrackTiming.prototype.send = function() {
  var timeSpent = this.endTime - this.startTime;

  var hourInMillis = 1000 * 60 * 60;

  if (0 < timeSpent && timeSpent < hourInMillis) {
    window._gaq.push(['_trackTiming', this.category, this.variable, timeSpent, this.label]);
  }

   return this;
}

Anulación de la tasa de muestreo y depuración

El método _trackTiming solo envía datos a Google Analytics con la misma velocidad para todas las métricas de velocidad del sitio que recopila Google Analytics. De forma predeterminada, se establece en el 1% de todos los visitantes.

En el caso de los sitios con mucho tráfico, el valor predeterminado está bien. Sin embargo, puedes aumentar la tasa de muestreo si configuras el parámetro opcional de tasa de muestreo de los sitios con menos tráfico. Por ejemplo:

_gaq.push(['_trackTiming', 'jQuery', 'Load Library', timeSpent, 'Google CDN', 50]);

Se recopilarán datos de _trackTiming del 50% de los visitantes.

También puedes configurar el método _setSiteSpeedSampleRate para establecer la tasa de muestreo de todos los tiempos de velocidad del sitio, incluido el método _trackTiming. Por ejemplo:

_gaq.push([‘_setSiteSpeedSampleRate’, 50]);

También se recopilarán datos de _trackTiming del 50% de los visitantes.

Por lo general, cuando pruebas y verificas una implementación de Google Analytics, tienes muy poco tráfico en el sitio que estás probando. Por lo tanto, suele ser útil aumentar la tasa de muestreo al 100% mientras realizas las pruebas.

Volver al principio

Seguimiento de otros eventos temporales

Si bien todo el ejemplo anterior se enfoca en usar el método _trackTiming para hacer un seguimiento del tiempo que se tarda en cargar los recursos, este método también se puede usar para realizar un seguimiento de duraciones generales de tiempo. Por ejemplo, podrías hacer un seguimiento de lo siguiente:

  • Es el tiempo que un visitante mira un video.
  • Es el tiempo que lleva completar un nivel en un juego.
  • Es el tiempo que un visitante dedica a leer una sección de un sitio web.

En cada uno de estos casos, puedes volver a usar el mismo objeto TimeTracker de JavaScript que se presentó anteriormente para simplificar la recopilación y el envío del tiempo dedicado a los datos a Google Analytics.