Search

Comment utiliser Python pour surveiller et mesurer la performance des sites web


Au cours du mois dernier, Google a annoncé un certain nombre d’avancées dans la façon dont il mesurera l’expérience des utilisateurs grâce à des indicateurs clés de vitesse et de performance.

Par coïncidence, j’ai travaillé à la mise au point d’un script Python qui utilise l’API Google PageSpeed Insights (PSI) pour collecter des mesures pour un certain nombre de pages à la fois, sans avoir besoin d’exécuter le test pour chaque URL individuelle.

Après les annonces de Google, j’ai pensé que le moment était venu de le partager et d’expliquer comment créer ce script Python pour débutants.

L’avantage de ce script est qu’une fois les bases établies, vous pourrez extraire un certain nombre de mesures différentes qui se trouvent dans le test de vitesse des pages, ainsi que dans l’analyse Lighthouse.

Une introduction aux mesures vitales du Web

Début mai, Google a introduit les « Core Web Vitals », qui sont un sous-ensemble de ses mesures clés de « Web Vitals ».

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

Ces mesures sont utilisées pour fournir des indications sur la qualité de l’expérience de l’utilisateur sur un site web.

Google les a décrites comme un moyen « d’aider à quantifier l’expérience de votre site et d’identifier les possibilités d’amélioration », soulignant ainsi leur évolution vers une focalisation sur l’expérience de l’utilisateur.

Les « Core Web Vitals » sont des mesures réelles, centrées sur l’utilisateur, qui mesurent les aspects clés de l’expérience de l’utilisateur : temps de chargement, interactivité et stabilité.

Je n’entrerai pas trop dans les détails dans ce post – vous pouvez en savoir plus ici – mais ces nouvelles mesures le sont :

  • La plus grande peinture contestataire.
  • Premier délai de saisie.
  • Décalage cumulatif de la mise en page.

LCP - FID - CLS

En outre, Google a annoncé la semaine dernière qu’il introduira un nouveau signal de classement de recherche qui combinera ces mesures avec les signaux d’expérience de page existants, tels que la convivialité pour les mobiles et la sécurité HTTPS, afin de garantir qu’il continue à servir des sites web de haute qualité aux utilisateurs.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

Suivi des mesures de performance

Cette mise à jour devrait intervenir en 2021 et Google a confirmé qu’aucune mesure immédiate n’est nécessaire.

Toutefois, afin de nous aider à nous préparer à ces changements, ils ont mis à jour les outils utilisés pour mesurer la vitesse des pages, notamment le PSI, le Google Lighthouse et le Google Search Console Speed Report.

Quel est le rôle de l’API de Pagespeed Insights ?

PageSpeed Insights de Google est un outil utile pour visualiser un résumé des performances d’une page web, et utilise à la fois des données de terrain et de laboratoire pour générer des résultats.

C’est un excellent moyen d’avoir un aperçu d’une poignée d’URL, car il est utilisé page par page.

Toutefois, si vous travaillez sur un site de grande envergure et que vous souhaitez obtenir des informations à grande échelle, l’API peut être utile pour analyser un certain nombre de pages à la fois, sans avoir besoin de saisir les URL individuellement.

Un script en Python pour mesurer la performance

J’ai créé le script Python suivant pour mesurer les performances clés à l’échelle, afin d’économiser le temps passé à tester manuellement chaque URL.

Ce script utilise Python pour envoyer des requêtes à l’API PSI de Google afin de collecter et d’extraire les mesures qui sont affichées à la fois dans PSI et Lighthouse.

J’ai décidé d’écrire ce script dans Google Colab car c’est un excellent moyen de commencer à écrire du Python et cela permet un partage facile, donc ce billet va passer par la configuration en utilisant Google Colab.

Toutefois, il peut également être exécuté localement, avec quelques modifications au niveau du chargement et du téléchargement des données.

Il est important de noter que certaines étapes peuvent prendre un certain temps, en particulier lorsque chaque URL passe par l’API, afin de ne pas la surcharger de requêtes.

Vous pouvez donc exécuter le script en arrière-plan et y revenir lorsque les étapes sont terminées.

Passons en revue les étapes nécessaires à la mise en place de ce scénario.

Étape 1 : Installer les paquets requis

Avant de commencer à écrire du code, nous devons installer certains paquets Python qui sont nécessaires avant de pouvoir utiliser le script. Ils sont faciles à installer grâce à la fonction d’importation.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

Les paquets dont nous aurons besoin sont les suivants :

  • urllib: Pour travailler avec, ouvrir, lire et analyser les URL.
  • json: Permet de convertir un fichier JSON en Python ou un fichier Python en JSON.
  • demande: Une bibliothèque HTTP pour envoyer toutes sortes de requêtes HTTP.
  • pandas: Principalement utilisé pour l’analyse et la manipulation des données, nous l’utilisons pour créer des DataFrames.
  • temps: Un module pour travailler avec les temps, nous l’utilisons pour fournir une pause entre les demandes.
  • fichiers: A partir de Google Colab, cela vous permettra de charger et de télécharger des fichiers.
  • io: L’interface par défaut utilisée pour accéder aux fichiers.
# Import required packages 
import json
import requests
import pandas as pd
import urllib
import time
from google.colab import files
import io 

Étape 2 : Établir une demande d’API

L’étape suivante consiste à mettre en place la demande API. Vous trouverez des instructions complètes ici, mais la commande ressemblera essentiellement à ceci :

https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url={yourURL}/&strategy=mobile/&key={yourAPIKey}

Cela vous permettra d’ajouter votre URL, votre stratégie (bureau ou mobile) et votre clé API.

Pour l’utiliser avec Python, nous utiliserons la bibliothèque de requêtes urllib urllib.request.urlopen et l’ajouter à une variable appelée résultat afin que nous puissions stocker les résultats et les utiliser à nouveau dans le script.

# Define URL  
url = 'https://www.example.co.uk'

# API request url
result = urllib.request.urlopen('https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url={}/&strategy=mobile'
.format(url)).read().decode('UTF-8')

print(result)

Étape 3 : Tester l’API

Afin de tester si l’API est correctement configurée, ainsi que pour comprendre ce qui est généré pendant le test, j’ai fait passer une URL par l’API en utilisant la méthode simple urllib.request.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

Une fois cette opération terminée, j’ai ensuite converti le résultat en un fichier json et l’ai téléchargé, afin d’en visualiser le résultat.

# Convert to json format
result_json = json.loads(result)

print(result_json)

with open('result.json', 'w') as outfile:
  json.dump(result_json, outfile)

files.download('result.json')

(Veuillez noter que cette méthode permet de convertir et de télécharger des fichiers JSON dans Google Colab).

Étape 4 : Lire le dossier JSON

Le fichier JSON ressemble généralement à ceci, lorsqu’il est ouvert dans l’éditeur de code de votre choix.

Lire le fichier JSON

Il est assez difficile à comprendre, mais l’utilisation d’un visualiseur JSON en ligne vous permettra de le convertir en une vue arborescente lisible.

vue arborescente lisible

Le fichier JSON affiche les données de terrain, qui sont stockées sous loadingExperience, et les données de laboratoire que vous pouvez trouver sous lighthouseResult.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

Afin d’extraire les mesures souhaitées, nous pouvons utiliser le format du fichier JSON, car nous sommes en mesure de voir quelle mesure se trouve sous chaque section.

Par exemple, First Input Delay se trouve sous loadingExperience.

Le premier délai de saisie se trouve sous chargementExperience

Alors que First Contentful Paint se trouve sous lighthouseResult.

First Contentful Paint se trouve sous lighthouseResult

Il existe de nombreux autres paramètres stockés dans le cadre des audits « LighthouseResult », tels que

  • Indice de vitesse.
  • Première Peinture Contentieuse.
  • Décalage cumulatif de la mise en page.

Étape 5 : Télécharger un CSV et le stocker en tant que dataframe Pandas

L’étape suivante consiste à télécharger un fichier CSV des URL que nous voulons faire passer par l’API de l’ISP. Vous pouvez générer une liste des URL de votre site à partir d’un outil d’exploration, tel que DeepCrawl.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

Comme nous utilisons l’API, je vous recommande d’utiliser ici un ensemble d’URL plus petit, surtout si vous avez un grand site.

Par exemple, vous pouvez utiliser les pages qui ont le plus haut niveau de trafic, ou les pages qui génèrent le plus de revenus. Par ailleurs, si votre site comporte des modèles, il serait bon d’en tester des ensembles.

Vous pouvez également ajouter un en-tête de colonne que nous utiliserons lors de l’itération de la liste. Assurez-vous que cela correspond au nom de l’en-tête de colonne dans le fichier CSV que vous téléchargez :

uploaded = files.upload()
#if your column header is something other than 'url' please define it here 
column_header='url'

(Veuillez noter que cette méthode est destinée à télécharger des fichiers CSV dans Google Colab).

Une fois ce dernier téléchargé, nous utiliserons la bibliothèque Pandas pour transformer le CSV en un DataFrame, que nous pourrons itérer dans les étapes suivantes.

# 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()

Le DataFrame ressemblera à ceci, en commençant par une indexation zéro.

dataframe

Étape 6 : Enregistrer les résultats dans un objet de réponse

L’étape suivante consiste à utiliser un pour la boucle pour itérer le DataFrame des URL que nous venons de créer par le biais de l’API de l’ISP.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

Une boucle for nous permet d’itérer à travers la liste que nous avons téléchargée et d’exécuter la commande pour chaque élément. Ensuite, nous pouvons enregistrer les résultats dans un objet de réponse et le convertir en un fichier JSON.

response_object = {}

# Iterate through the df
for x in range(0, len(df)):

        # Define request parameter
        url = df.iloc[x][column_header]

        # Make request
        pagespeed_results = urllib.request.urlopen('https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url={}&strategy=mobile'.format(url)).read().decode('UTF-8')

        # Convert to json format
        pagespeed_results_json = json.loads(pagespeed_results)

        # Insert returned json response into response_object
        response_object[url] = pagespeed_results_json
        time.sleep(30)
        
        print(response_object[url])

Nous utiliserons x dans la gamme ici, qui représentera les URL que nous parcourons dans la boucle, ainsi que (0, len) ce qui permet à la boucle de passer par toutes les URL du DataFrame, quel qu’en soit le nombre.

Le objet de réponse empêche les URL de se superposer les unes aux autres lorsque vous passez en boucle et nous permet de sauvegarder les données pour une utilisation ultérieure.

C’est également là que nous utiliserons la variable d’en-tête de colonne pour définir le paramètre de demande d’URL, avant de le convertir en un fichier JSON.

J’ai également réglé le temps de sommeil ici à 30 secondes, pour réduire le nombre d’appels API consécutifs.

Vous pouvez également ajouter une clé API à la fin de la commande URL si vous souhaitez effectuer des requêtes plus rapides.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

L’indentation est également importante ici car, comme chaque étape fait partie de la boucle de for, elle doit être indentée dans le commandement.

Étape 7 : Créer une base de données pour stocker les réponses

Nous devons également créer un DataFrame qui stockera les mesures que nous voulons extraire de l’objet de réponse.

Un DataFrame est une structure de données similaire à un tableau, avec des colonnes et des lignes qui stockent les données. Il suffit d’ajouter une colonne pour chaque métrique et de la nommer de manière appropriée :

# 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)

Pour les besoins de ce script, j’ai utilisé les mesures de Core Web Vital, ainsi que les mesures supplémentaires de chargement et d’interactivité utilisées dans la version actuelle de Lighthouse.

Ces mesures ont chacune un poids différent qui est ensuite utilisé dans la note globale de performance :

Vous pouvez en savoir plus sur chaque mesure, ainsi que sur la manière d’interpréter les résultats, sur leurs pages de renvoi individuelles qui sont liées ci-dessus.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

J’ai également choisi d’inclure l’indice de vitesse et la catégorie générale qui donnera un score soit lent, soit moyen, soit rapide.

Étape 8 : Extraire les mesures de l’objet de la réponse

Une fois l’objet de réponse enregistré, nous pouvons le filtrer et en extraire les mesures que nous voulons.

Ici, nous utiliserons une fois de plus une boucle for pour itérer à travers le fichier objet de réponse et établir une séquence d’index de liste pour renvoyer uniquement les mesures spécifiques.

Pour cela, nous définirons le nom de la colonne du DataFrame, ainsi que la catégorie spécifique de l’objet de réponse dont nous tirerons chaque métrique, pour chaque 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']

J’ai mis en place ce script pour extraire les mesures clés que j’ai mentionnées ci-dessus afin que vous puissiez l’utiliser immédiatement pour collecter ces données.

Toutefois, il est possible d’extraire un certain nombre d’autres mesures utiles qui peuvent être trouvées dans les tests de l’ISP, ainsi que dans l’analyse Lighthouse.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

C’est là que le fichier JSON est utile pour examiner la place de chaque mesure dans la liste.

Par exemple, pour extraire des mesures des audits Lighthouse, comme la valeur d’affichage de Time to Interactive, vous utiliserez ce qui suit :

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

Une fois de plus, il est important de s’assurer que chacun d’entre eux se trouve dans la boucle, sinon ils ne seront pas inclus dans l’itération et un seul résultat sera généré pour une URL.

Notre DataFrame final ressemblera à ceci ;

final dataframe

Étape 9 : Transformer le DataFrame en un fichier CSV

L’étape finale consiste à créer un fichier récapitulatif pour rassembler tous les résultats, afin de les transformer en un format que nous pouvons facilement analyser, par exemple, un fichier CSV.

summary = df_pagespeed_results

df_pagespeed_results.head()

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

(Veuillez noter que cette méthode permet de convertir et de télécharger des fichiers CSV dans Google Colab).

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

Approfondir les données

Toutes les métriques que nous avons exportées sont actuellement stockées sous forme de chaînes de caractères, un type de données Python pour le texte et les caractères.

Comme certaines des mesures que nous extrayons sont en fait des valeurs numériques, vous pouvez transformer les chaînes de caractères en types de données numériques, tels que des nombres entiers et des nombres à virgule flottante.

Les nombres entiers, également appelés int, sont le type de données pour les nombres entiers, tels que 1 et 10.

Les nombres à virgule flottante, également appelés « float », sont des nombres à virgule décimale tels que 1,0 et 10,1.

La première consiste à remplacer le caractère « s » (utilisé pour représenter les secondes) par un espace vide.

Pour ce faire, nous utilisons le .str.replace sur chaque colonne.

#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', '')

Nous utiliserons alors la .astype() pour convertir les chaînes de caractères en nombres entiers ou en nombres à virgule flottante :

#Turn strings into intergers or floats
df_pagespeed_results['Largest_Contentful_Paint'] = df_pagespeed_results.Largest_Contentful_Paint.astype(float)
df_pagespeed_results['Cumulative_Layout_Shift'] = df_pagespeed_results.Cumulative_Layout_Shift.astype(int)
df_pagespeed_results['First_Contentful_Paint'] = df_pagespeed_results.First_Contentful_Paint.astype(float)
df_pagespeed_results['Time_to_Interactive'] = df_pagespeed_results.Time_to_Interactive.astype(float)
df_pagespeed_results['Speed_Index'] = df_pagespeed_results.Speed_Index.astype(float)

Une fois que nous avons fait cela, vous pouvez utiliser un certain nombre de méthodes différentes pour évaluer les données plus en profondeur.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

Par exemple, vous pouvez utiliser des bibliothèques de visualisation de données telles que matplotlib ou seaborn pour visualiser les mesures, ainsi que pour mesurer leur évolution dans le temps et regrouper les résultats en seaux lents, moyens et rapides.

Je ne les aborderai pas dans cet article, car nous en avons déjà beaucoup parlé, mais n’hésitez pas à me contacter si vous souhaitez en savoir plus.

En conclusion

Ce script m’a finalement aidé à mesurer la vitesse des pages clés et les performances d’un groupe d’URL, ainsi qu’à visualiser les résultats afin d’identifier les pages à améliorer.

Il vous permet également de suivre les résultats dans le temps et de quantifier les améliorations apportées.

J’ai également créé un script spécifique pour mesurer les percentiles et les catégories pour les trois « Core Web Vitals ». Vous pouvez le trouver ici.

J’espère que cela a été utile à tous ceux qui cherchent à automatiser leurs tests de performance et à explorer davantage l’API de l’ISP.

PUBLICITÉ

CONTINUER LA LECTURE CI-DESSOUS

N’hésitez pas à enregistrer une copie de ce fichier Colab et à l’utiliser pour vous aider à mesurer et à contrôler la vitesse de votre page, ou à suivre les étapes pour écrire la vôtre. Vous pouvez accéder à tous les extraits de code que j’ai partagés dans cet article ici.

Plus de ressources :


Crédits image

Toutes les captures d’écran prises par l’auteur, juin 2020



Auteur/autrice

Partager:

Articles Similaires