Cómo automatizar la medición de los Core Web Vitals con la API de Wattspeed y Google App Script

Contexto de los Core Web Vitals

Los Core Web Vitals son el subconjunto de Web Vitals que se aplica a todas las páginas web, todos los propietarios de sitios deben medirlos y aparecerán en todas las herramientas de Google. Cada uno de los Core Web Vitals representa una faceta distinta de la experiencia del usuario, se puede medir en el campo y refleja la experiencia en el mundo real de un resultado indispensable centrado en el usuario.

Google Developers

Los Core Web Vitals son los nuevos KPI’s de web performance que Google introdujo en junio de 2021 y que desde entonces no han dejado de sonar en nuestro día a día. Suponen unos factores claramente enfocados en ofrecer una buena experiencia de navegación al usuario y deberíamos tenerlos presentes sí o sí. Aunque Google los ha vendido como un factor de posicionamiento directo lo cierto es que la mayor parte del sector no ha visto cambios significativos a lo largo de este año. Haya sido o no significativo su impacto, lo cierto es que son métricas que deberíamos intentar cuidar, ya incluso no por SEO y su posible impacto en el posicionamiento, si no por asegurarnos que ofrecemos una experiencia web positiva; al fin de cuentas, tener unos buenos valores en Core Web Vitals sí que tienen un impacto real en la experiencia de navegación de tu página web, independientemente del posible impacto que pueda tener sobre tu SEO, y esto puede repercutir indirectamente en otras métricas más importantes como las propias conversiones.

Independientemente del posible impacto que pueda tener en el SEO, deberíamos poner foco en ofrecer unos buenos valores de web performance para ofrecer una experiencia web que facilite tanto la navegación como la conversión.

¿Cómo medir los Core Web Vitals?

Como todos los sabemos, las métricas de rendimiento se pueden medir a través de herramientas que ofrecen datos de campo y laboratorio. Existen multitud de ellas que todos conocemos:

  • Page Speed Insights
  • Lighthouse
  • GTMetrix
  • WebPageTest
  • API de CrUX y Data Studio, Screaming Frog, etc.
  • etc.

Las herramientas son variadas y todas tienen su forma particular de usarlas, sin embargo, hoy os quiero hablar de una en concreto que nos ofrece una API muy sencilla de utilizar que será la que nos ayude a montar nuestro informe automatizado: Wattspeed.

Wattspeed para monitorizar el performance de tu web

Para mi el valor diferencial que ofrece esta herramienta es la posibilidad de hacer seguimiento del performance de una serie de URLs e ir guardando su histórico, lo que nos puede ser muy útil para evaluar el impacto de posibles implementaciones que llevemos a cabo y ver su evolución a lo largo del tiempo, por ejemplo.

Wattspeed nos permite guardar el histórico de las URLs sobre las que hagamos seguimiento para ir viendo su evolución a lo largo del tiempo.

Automatizar informe con la API de Wattspeed y Google App Script

Más allá de lo que la propia herramienta ofrece en su interfaz, lo que vamos a hacer es trabajar los datos que ofrece su API y a partir de los cuales vamos a montar nuestro propio informe automatizado. El hecho de tener que acceder a la propia herramienta e ir accediendo a cada URL para ver sus datos e histórico no es un proceso ágil para evaluar el rendimiento global de ciertos KPIs. Por ello, lo que pretendo es crear mi propio informe con los datos de los KPIs que me interesen únicamente y con todas las URLs en un mismo lugar.

El resultado del informe automatizado que tendremos al final del proceso es este:

Con los datos de la API de Wattspeed y Google App Script podemos crear un informe automatizado fácilmente.

La API de Wattspeed

A la hora de hacer seguimiento de una URL en Wattspeed, la herramienta nos ofrece una URL a la que hacer una request para obtener los datos de su performance. Básicamente hay que hacer una petición GET a la URL que nos ofrece y a partir de ahí ir trabajando los valores que queremos obtener, como muchas otras APIs:

Wattspeed nos ofrece una URL a la que hacer una petición GET para obtener los valores del experimento.

Los datos que nos devuelve la API es un JSON al que tendremos que acceder para obtener los valores que nos interesan; en este caso los valores de los Core Web Vitals:

La API de Wattspeed nos devuelve un JSON a partir del cual obtener y trabajar los datos.

Google sheets

El entorno donde vamos a crear nuestro informe automatizado será en Google Sheets dada la facilidad que nos permite Google App Script de crear nuestros propios scripts y automatizaciones.

En Google Sheet tendrías que dejar preparada la estructura donde ir pintando los datos automáticamente (luego veremos como automatizamos el proceso).

Vamos a recoger los datos de:

  • LCP
  • CLS
  • TBT
  • Server Response Time

Vamos a ir recogiendo estos datos semanalmente durante 3 meses, y por tanto, la estructura del informe quedaría así con dos URLs de ejemplo:

Google App Script: Código

Para trabajar con la API tendremos que ir al editor de código de Google Sheets:

menu app scripts

Para hacer la Request simplemente tenemos que llamar al método fetch() de la clase UrlFetchApp y parsear la respuesta a formato JSON:

options = {
    'method': 'get'
  }

const response1 = UrlFetchApp.fetch('https://api.wattspeed.com/update?token=BI8Kqlh0W7rJQrwwwgKkaKMNTgZEccbUi2ja1s0H9xqnDzcrZ3WmmMZUr9BfCPUt', options).getContentText();

const dataParsed1 = JSON.parse(response1);

Una vez tengamos la respuesta parseada, tendríamos que investigar un poco el JSON e identificar donde se encuentran los valores que queremos capturar. En este caso, serían estos:

lcp1 = dataParsed1['body']['audits']['largest-contentful-paint']['displayValue']
tbt1 = dataParsed1['body']['audits']['total-blocking-time']['displayValue']
cls1 = dataParsed1['body']['audits']['cumulative-layout-shift']['displayValue']
serverResponse1 = dataParsed1['body']['audits']['server-response-time']['displayValue']

Como quiero los valores en formato número, y me devuelve ciertos valores extraños que no queremos, tenemos que aplicar ciertos métodos para depurar los valores:

lcp1 = dataParsed1['body']['audits']['largest-contentful-paint']['displayValue'].replace('s', '').replace('.', ',').trim()
tbt1 = dataParsed1['body']['audits']['total-blocking-time']['displayValue'].replace('ms', '').trim()
cls1 = dataParsed1['body']['audits']['cumulative-layout-shift']['displayValue'].replace('.', ',')
serverResponse1 = dataParsed1['body']['audits']['server-response-time']['displayValue'].replace('Root document took ', '').replace('ms', '').trim()

Ahora habría que replicar este proceso para tantas URLs como queramos medir.

Una vez recogidos ya los valores, habría que pensar en el modo en el que los pintamos en Google Sheets.

El código completo para recoger los datos de la API y pintarlos sería este (os dejo comentarios):

//Creo un array de letras para ir cambiando de columna
letras = 'CDEFGHIJKLMNOPQRSTUVWYZ'
abecedario = Array.from(letras)

function GetSpeedData() {

  ss = SpreadsheetApp.getActiveSpreadsheet()
  options = {
    'method': 'get',
    'muteHttpExceptions': true
  }

for(letter in abecedario){
  if(!ss.getRange(abecedario[letter]+'4:'+abecedario[letter]+'4').getValue()){
  //URL 1
  const response1 = UrlFetchApp.fetch('https://api.wattspeed.com/update?token=BI8Kqlh0W7rJQrwwwgKkaKMNTgZEccbUi2ja1s0H9xqnDzcrZ3WmmMZUr9BfCPUt', options).getContentText();
  const dataParsed1 = JSON.parse(response1);

  //URL 2
  const response2 = UrlFetchApp.fetch('https://api.wattspeed.com/update?token=BI8Kqlh0W7rJQrwwwgKkaDxSliZ0WUrXoIp8gTKFXSH5syyiPAcewmnOffDJqKh2', options).getContentText();
  const dataParsed2 = JSON.parse(response2);

  //URL 3
  const response3 = UrlFetchApp.fetch('https://api.wattspeed.com/update?token=BI8Kqlh0W7rJQrwwwgKkaBPDMB3ZL7LBtUhidOz0q51qTbJrAr8HzvG4sHAVUZaLI4aOECf%2B%2BHDI1zHdk6XjX9dL%2FP73NsxvKbLGrCm%2FNCmHdu70bu0NQ9k6E5e5P31Q', options).getContentText();
  const dataParsed3 = JSON.parse(response3);


  //Values
  lcp1 = dataParsed1['body']['audits']['largest-contentful-paint']['displayValue'].replace('s', '').replace('.', ',').trim()
  tbt1 = dataParsed1['body']['audits']['total-blocking-time']['displayValue'].replace('ms', '').trim()
  cls1 = dataParsed1['body']['audits']['cumulative-layout-shift']['displayValue'].replace('.', ',')
  serverResponse1 = dataParsed1['body']['audits']['server-response-time']['displayValue'].replace('Root document took ', '').replace('ms', '').trim()
  
  
  lcp2 = dataParsed2['body']['audits']['largest-contentful-paint']['displayValue'].replace('s', '').replace('.', ',').trim()
  tbt2 = dataParsed2['body']['audits']['total-blocking-time']['displayValue'].replace('ms', '').trim()
  cls2 = dataParsed2['body']['audits']['cumulative-layout-shift']['displayValue'].replace('.', ',')
  serverResponse2 = dataParsed2['body']['audits']['server-response-time']['displayValue'].replace('Root document took ', '').replace('ms', '').trim()


  lcp3 = dataParsed3['body']['audits']['largest-contentful-paint']['displayValue'].replace('s', '').replace('.', ',').trim()
  tbt3 = dataParsed3['body']['audits']['total-blocking-time']['displayValue'].replace('ms', '').trim()
  cls3 = dataParsed3['body']['audits']['cumulative-layout-shift']['displayValue'].replace('.', ',')
  serverResponse3 = dataParsed3['body']['audits']['server-response-time']['displayValue'].replace('Root document took ', '').replace('ms', '').trim()

  //Escritura de valores
  ss.getRange(abecedario[letter]+'4:'+abecedario[letter]+'4').setValue(lcp1)
  ss.getRange(abecedario[letter]+'5:'+abecedario[letter]+'5').setValue(tbt1)
  ss.getRange(abecedario[letter]+'6:'+abecedario[letter]+'6').setValue(cls1)
  ss.getRange(abecedario[letter]+'8:'+abecedario[letter]+'8').setValue(serverResponse1)

  ss.getRange(abecedario[letter]+'14:'+abecedario[letter]+'14').setValue(lcp2)
  ss.getRange(abecedario[letter]+'15:'+abecedario[letter]+'15').setValue(tbt2)
  ss.getRange(abecedario[letter]+'16:'+abecedario[letter]+'16').setValue(cls2)
  ss.getRange(abecedario[letter]+'18:'+abecedario[letter]+'18').setValue(serverResponse2)

  ss.getRange(abecedario[letter]+'25:'+abecedario[letter]+'25').setValue(lcp3)
  ss.getRange(abecedario[letter]+'26:'+abecedario[letter]+'26').setValue(tbt3)
  ss.getRange(abecedario[letter]+'27:'+abecedario[letter]+'27').setValue(cls3)
  ss.getRange(abecedario[letter]+'29:'+abecedario[letter]+'29').setValue(serverResponse3)
  
  //Hago un break para que no pase a la siguiente columna
  break
  }
  
}  
}

Por último, lo que tenemos que hacer para recoger estos datos automáticamente y olvidarnos de hacer nada más, sería crear un activador en Google App Script de tal modo que ejecute la función periódicamente (en nuestro caso semanalmente).

Google App Script nos permite crear activadores para automatizar la ejecución de nuestras funciones.

Resumen

Recordemos todos los pasos para conseguir nuestro informe automatizado:

  • Trackear las URLs en Wattspeed de las que queramos hacer seguimiento y obtener las URLs de la API a las que hacer la Request.
  • Montar la estructura del informe en Google Sheets donde ir pintando los datos.
  • Crear nuestra función donde hacemos la request, obtenemos los datos y los pintamos en la hoja.
  • Crear un activador para que ejecute periódicamente la función y se vayan pintando los datos.

Sobre el autor

Alex Romero Lopez, Consultor SEO en España
alejandro.romerolopez95@gmail.com Web Otros artículos del autor

Especialista SEO con gran foco en el área técnica. Entusiasta de la programación, en especial Python y Javascript, y la aplicación de ésta en el ámbito SEO para automatizar procesos o profundizar en ciertos ámbitos como el web scraping o el uso de APIs. He trabajado en proyectos SEO de muy diferente tamaño y sector lo que me permite obtener una perspectiva 360º de cómo trabajarlo.

Deja un comentario