Cómo usar Python para monitorear y medir el rendimiento del sitio web

Durante el √ļltimo mes, Google ha anunciado una serie de avances sobre c√≥mo medir√°n la experiencia del usuario a trav√©s de la velocidad clave y las m√©tricas de rendimiento.

Casualmente, he estado trabajando en la creaci√≥n de un script de Python que utiliza la API de Google PageSpeed ‚Äč‚ÄčInsights (PSI) para recopilar m√©tricas para varias p√°ginas a la vez, sin necesidad de ejecutar la prueba para cada URL individual.

Después de los anuncios de Google, pensé que ahora sería el momento perfecto para compartirlo, así como para explicar cómo puedes crear este script Python para principiantes.

Lo mejor de la secuencia de comandos es que, una vez que tenga las bases establecidas, podrá extraer una serie de métricas diferentes que se pueden encontrar en la prueba de velocidad de la página, así como en el análisis de Lighthouse.

Una introducción a las métricas vitales web

A principios de mayo, Google presentó Core Web Vitals, que son un subconjunto de sus métricas clave de Web Vitals.

Estas métricas se utilizan para proporcionar orientación sobre la calidad de la experiencia del usuario en un sitio web.

Google los ha descrito como una forma de “ayudar a cuantificar la experiencia de su sitio e identificar oportunidades para mejorar”, destacando a√ļn m√°s su cambio para centrarse en la experiencia del usuario.

Core Web Vitals son métricas centradas en el usuario del mundo real que miden los aspectos clave de la experiencia del usuario; tiempo de carga, interactividad y estabilidad.

No voy a entrar en demasiados detalles al explicar esto en esta publicación, puede encontrar más información aquí, pero estas nuevas métricas son:

  • La pintura contenta m√°s grande.
  • Primer retardo de entrada.
  • Cambio de dise√Īo acumulativo.

LCP - FID - CLS

Adem√°s de esto, Google anunci√≥ la semana pasada que presentar√°n una nueva se√Īal de clasificaci√≥n de b√ļsqueda que combinar√° estas m√©tricas junto con las se√Īales de experiencia de p√°gina existentes, como la compatibilidad con dispositivos m√≥viles y la seguridad HTTPS, para garantizar que contin√ļen sirviendo sitios web de alta calidad a los usuarios

Monitoreo de métricas de rendimiento

Se espera que esta actualización se implemente en 2021 y Google ha confirmado que no es necesario tomar medidas inmediatas.

Sin embargo, para ayudarnos a prepararnos para estos cambios, han actualizado las herramientas utilizadas para medir la velocidad de la p√°gina, incluidos PSI, Google Lighthouse y el Informe de velocidad de Google Search Console.

¬ŅD√≥nde entra en juego la API de Pagespeed Insights?

PageSpeed ‚Äč‚ÄčInsights de Google es una herramienta √ļtil para ver un resumen del rendimiento de una p√°gina web y utiliza tanto datos de campo como de laboratorio para generar resultados.

Es una excelente manera de obtener una visi√≥n general de un pu√Īado de URL, ya que se utiliza p√°gina por p√°gina.

Sin embargo, si está trabajando en un sitio grande y desea obtener información a gran escala, la API puede ser beneficiosa para analizar varias páginas a la vez, sin necesidad de conectar las URL individualmente.

Un script de Python para medir el rendimiento

He creado el siguiente script de Python para medir las métricas clave de rendimiento a escala, a fin de ahorrar tiempo dedicado a probar manualmente cada URL.

Este script utiliza Python para enviar solicitudes a la API de Google PSI para recopilar y extraer las métricas que se muestran tanto en PSI como en Lighthouse.

Decidí escribir este script en Google Colab, ya que es una excelente manera de comenzar a escribir Python y permite compartirlo fácilmente, por lo que esta publicación se ejecutará a través de la configuración usando Google Colab.

Sin embargo, también se puede ejecutar localmente, con algunos ajustes en la carga y descarga de datos.

Es importante tener en cuenta que algunos pasos pueden tardar un tiempo en completarse, especialmente cuando cada URL se ejecuta a través de la API, para no sobrecargarla con solicitudes.

Por lo tanto, puede ejecutar el script en segundo plano y volver a él cuando se hayan completado los pasos.

Veamos los pasos necesarios para poner este script en funcionamiento.

Paso 1: Instale los paquetes requeridos

Antes de comenzar a escribir cualquier código, necesitamos instalar algunos paquetes de Python que son necesarios antes de poder usar el script. Estos son fáciles de instalar utilizando la función de importación.

Los paquetes que necesitaremos son:

  • urllib: Para trabajar con, abrir, leer y analizar URL.
  • json: Le permite convertir un archivo JSON a Python o un archivo Python a JSON.
  • peticiones: Una biblioteca HTTP para enviar todo tipo de solicitudes HTTP.
  • pandas: Utilizado principalmente para el an√°lisis y la manipulaci√≥n de datos, lo estamos utilizando para crear marcos de datos.
  • hora: Un m√≥dulo para trabajar con tiempos, lo estamos utilizando para proporcionar un intervalo de tiempo entre solicitudes.
  • archivos: Desde Google Colab, esto le permitir√° cargar y descargar archivos.
  • io: La interfaz predeterminada utilizada para acceder a los archivos.
# Import required packages 
import json
import requests
import pandas as pd
import urllib
import time
from google.colab import files
import io 

Paso 2: configurar una solicitud de API

El siguiente paso es configurar la solicitud de API. Las instrucciones completas se pueden encontrar aquí, pero esencialmente el comando se verá así:

urllib.request.urlopen y agréguelo a una variable llamada (Tenga en cuenta que este método es para convertir y descargar archivos JSON en Google Colab).

Paso 4: lee el archivo JSON

El archivo JSON generalmente se verá así, cuando se abre en el editor de código de su elección.

Lea el archivo JSON

Es bastante difícil de entender, pero el uso de un visor JSON en línea le permitirá convertirlo en una vista de árbol legible.

vista de √°rbol legible

El archivo JSON muestra datos de campo, que se almacenan en loadingExperience, y datos de laboratorio que puede encontrar en lighthouseResult.

Para extraer las métricas deseadas, podemos utilizar el formato del archivo JSON, ya que podemos ver qué métrica se encuentra debajo de cada sección.

Por ejemplo, el primer retraso de entrada se encuentra en loadingExperience.

El primer retraso de entrada se encuentra en loadingExperience

Mientras que First Contentful Paint se encuentra en lighthouseResult.

La primera pintura contenta se encuentra bajo lighthouseResult

Hay muchas otras métricas almacenadas bajo las auditorías de lighthouseResult, como:

  • √ćndice de velocidad.
  • Primera pintura contenta.
  • Cambio de dise√Īo acumulativo.

Paso 5: cargue un CSV y almacene como un marco de datos de Pandas

El siguiente paso es cargar un archivo CSV de URL que queremos ejecutar a través de la API PSI. Puede generar una lista de las URL de su sitio desde una herramienta de rastreo, como DeepCrawl.

Como estamos utilizando la API, recomendar√≠a usar un conjunto de URL de muestra m√°s peque√Īo aqu√≠, especialmente si tiene un sitio grande.

Por ejemplo, podría usar páginas con los niveles más altos de tráfico, o páginas que generan la mayor cantidad de ingresos. Alternativamente, si su sitio tiene plantillas, sería ideal para probar conjuntos de estas.

También puede agregar un (Tenga en cuenta que este método es para cargar archivos CSV en Google Colab).

Una vez que esto se haya cargado, usaremos la biblioteca Pandas para convertir el CSV en un DataFrame, que podemos recorrer en los siguientes pasos.

# Get the filename from the upload so we can read it into a CSV.
for key in uploaded.keys():
  filename = key
# Read the selected file into a Pandas Dataframe
df = pd.read_csv(io.BytesIO(uploaded[filename]))

df.head()

El DataFrame se verá así, comenzando con la indexación cero.

marco de datos

Paso 6: guarde los resultados en un objeto de respuesta

El siguiente paso implica el uso de ax en el rango aquí, que representará las URL que estamos ejecutando a través del bucle, así como el objeto de respuesta evita que las URL se anulen entre sí a medida que avanza y nos permite guardar los datos para su uso futuro.

Aquí también es donde usaremos la variable de encabezado de columna para definir el parámetro de solicitud de URL, antes de convertirlo a un archivo JSON.

También configuré el tiempo para dormir aquí en 30 segundos, para reducir la cantidad de llamadas API realizadas consecutivamente.

Alternativamente, puede agregar una clave API al final del comando URL si desea hacer solicitudes m√°s r√°pidas.

La sangría también es importante aquí porque, como cada paso es parte del ciclo for, deben sangrarse dentro del comando.

Paso 7: crear un marco de datos para almacenar las respuestas

También necesitamos crear un DataFrame que almacene las métricas que queremos extraer del objeto de respuesta.

Un DataFrame es una estructura de datos similar a una tabla, con columnas y filas que almacenan datos. Simplemente necesitamos agregar una columna para cada métrica y nombrarla apropiadamente, así:

# Create dataframe to store responses
df_pagespeed_results = pd.DataFrame(columns=
          ['url',
          'Overall_Category',
          'Largest_Contentful_Paint',
          'First_Input_Delay',
          'Cumulative_Layout_Shift',
          'First_Contentful_Paint',
          'Time_to_Interactive',
          'Total_Blocking_Time',
          'Speed_Index'])  

print(df_pagespeed_results)

Para el propósito de este script, he utilizado las métricas de Core Web Vital, junto con las métricas adicionales de carga e interactividad utilizadas en la versión actual de Lighthouse.

Estas métricas tienen pesos diferentes que luego se utilizan en la puntuación de rendimiento general:

Puede obtener más información sobre cada métrica, junto con cómo interpretar los puntajes, en sus páginas de destino individuales que están vinculadas anteriormente.

También he elegido incluir el índice de velocidad y la categoría general que proporcionará un puntaje lento, promedio o rápido.

Paso 8: extraer las métricas del objeto de respuesta

Una vez que tenemos guardado el objeto de respuesta, ahora podemos filtrar esto y extraer solo las métricas que queremos.

Aquí, una vez más, utilizaremos un bucle for para recorrer el archivo de objetos de respuesta y establecer una secuencia de índices de lista para devolver solo las métricas específicas.

Para esto, definiremos el nombre de la columna del DataFrame, así como la categoría específica del objeto de respuesta del que extraeremos cada métrica, para cada URL.

for (url, x) in zip(
    response_object.keys(),
    range(0, len(response_object))
):

        # URLs
        df_pagespeed_results.loc[x, 'url'] =
            response_object[url]['lighthouseResult']['finalUrl']

        # Overall Category
        df_pagespeed_results.loc[x, 'Overall_Category'] =
            response_object[url]['loadingExperience']['overall_category']   

        # Core Web Vitals     

        # Largest Contentful Paint    
        df_pagespeed_results.loc[x, 'Largest_Contentful_Paint'] =
        response_object[url]['lighthouseResult']['audits']['largest-contentful-paint']['displayValue']

        # First Input Delay 
        fid = response_object[url]['loadingExperience']['metrics']['FIRST_INPUT_DELAY_MS']
        df_pagespeed_results.loc[x, 'First_Input_Delay'] = fid['percentile']

        # Cumulative Layout Shift    
        df_pagespeed_results.loc[x, 'Cumulative_Layout_Shift'] =
        response_object[url]['lighthouseResult']['audits']['cumulative-layout-shift']['displayValue']

        # Additional Loading Metrics 

        # First Contentful Paint 
        df_pagespeed_results.loc[x, 'First_Contentful_Paint'] =
        response_object[url]['lighthouseResult']['audits']['first-contentful-paint']['displayValue']

        # Additional Interactivity Metrics 

        # Time to Interactive  
        df_pagespeed_results.loc[x, 'Time_to_Interactive'] =
        response_object[url]['lighthouseResult']['audits']['interactive']['displayValue']

        # Total Blocking Time   
        df_pagespeed_results.loc[x, 'Total_Blocking_Time'] =
        response_object[url]['lighthouseResult']['audits']['total-blocking-time']['displayValue']

        # Speed Index
        df_pagespeed_results.loc[x, 'Speed_Index'] =
        response_object[url]['lighthouseResult']['audits']['speed-index']['displayValue']

He configurado este script para extraer las métricas clave que mencioné anteriormente para que pueda usarlo de inmediato para recopilar estos datos.

Sin embargo, es posible extraer una serie de otras m√©tricas √ļtiles que se pueden encontrar tanto en las pruebas de PSI como en el an√°lisis de Lighthouse.

Aqu√≠ es donde el archivo JSON es √ļtil para revisar d√≥nde se encuentra cada m√©trica en la lista.

Por ejemplo, al extraer métricas de las auditorías de Lighthouse, como el valor de visualización de Time to Interactive, usaría lo siguiente:

df_pagespeed_results.loc[x, 'Time_to_Interactive'] =
response_object[url]['lighthouseResult']['audits']['interactive']['displayValue']

Una vez más, es importante asegurarse de que cada uno de estos se encuentre dentro del ciclo, de lo contrario no se incluirán en la iteración y solo se generará un resultado para una URL.

Nuestro DataFrame final se verá así;

marco de datos final

Paso 9: Convierta el DataFrame en un archivo CSV

El paso final es crear un archivo de resumen para recopilar todos los resultados, para que podamos convertirlo en un formato que podamos analizar f√°cilmente, por ejemplo, un archivo CSV.

summary = df_pagespeed_results

df_pagespeed_results.head()

#Download csv file 
summary.to_csv('pagespeed_results.csv')
files.download('pagespeed_results.csv')

.str.replace método en cada columna.

#Replace the 's' with a blank space so we can turn into numbers
df_pagespeed_results['Largest_Contentful_Paint'] = df_pagespeed_results.Largest_Contentful_Paint.str.replace('s', '')
df_pagespeed_results['First_Contentful_Paint'] = df_pagespeed_results.First_Contentful_Paint.str.replace('s', '')
df_pagespeed_results['Time_to_Interactive'] = df_pagespeed_results.Time_to_Interactive.str.replace('s', '')
df_pagespeed_results['Total_Blocking_Time'] = df_pagespeed_results.Total_Blocking_Time.str.replace('ms', '')
df_pagespeed_results['Speed_Index'] = df_pagespeed_results.Speed_Index.str.replace('s', '')

Luego usaremos el Créditos de imagen

Todas las capturas de pantalla tomadas por el autor, junio de 2020