Une introduction à l'exécution de Lighthouse par programmation

Publié: 2022-03-10
Résumé rapide ↬ Pouvoir exécuter la suite d'analyse Google Lighthouse par programmation offre de nombreux avantages, en particulier pour les applications Web plus volumineuses ou plus complexes. L'utilisation de Lighthouse par programmation permet aux ingénieurs de mettre en place une surveillance de la qualité pour les sites qui nécessitent plus de personnalisation que ne le permettent les applications simples de Lighthouse (telles que Lighthouse CI). Cet article contient une brève introduction à Lighthouse, décrit les avantages de son exécution par programmation et décrit une configuration de base.

Lighthouse est la suite d'outils d'analyse de la qualité des sites Web de Google. Il vous permet d'évaluer les performances, l'accessibilité, le référencement, etc. de votre site. Il est également hautement configurable, ce qui le rend suffisamment flexible pour être utile à tous les sites, des plus simples aux plus complexes. Cette flexibilité comprend plusieurs manières différentes d'exécuter les tests, vous permettant de choisir la méthode qui convient le mieux à votre site ou à votre application.

L'un des moyens les plus simples d'exécuter Lighthouse consiste à utiliser le panneau DevTools Lighthouse de Chrome. Si vous ouvrez votre site dans Chrome, puis ouvrez les DevTools de Chrome, vous devriez voir un onglet "Lighthouse". À partir de là, si vous cliquez sur "Générer un rapport", vous devriez obtenir un rapport complet des mesures de qualité de votre site.

Ce sur quoi je me concentre dans cet article, cependant, se situe à l'autre extrémité du spectre. L'exécution de Lighthouse par programmation avec JavaScript nous permet de configurer des exécutions personnalisées, de sélectionner et de choisir les fonctionnalités que nous voulons tester, de collecter et d'analyser les résultats et de spécifier des options de configuration uniques à nos sites et applications.

Par exemple, vous travaillez peut-être sur un site accessible via plusieurs URL, chacune avec ses propres données et style et peut-être même un balisage que vous souhaitez pouvoir analyser. Ou peut-être souhaitez-vous rassembler les données de chaque test et les compiler ou les analyser de différentes manières. Avoir la possibilité de choisir comment vous souhaitez exécuter une analyse Lighthouse en fonction de ce qui fonctionne le mieux pour votre site ou votre application facilite la surveillance de la qualité du site et l'identification des problèmes avec votre site avant qu'ils ne s'accumulent ou ne causent trop de problèmes pour votre utilisateurs du site.

L'exécution de Lighthouse par programmation n'est pas le meilleur choix pour tous les sites et je vous encourage à explorer toutes les différentes méthodes que l'équipe Lighthouse a conçues pour utiliser l'outil. Si vous décidez d'utiliser Lighthouse par programmation, cependant, les informations et le didacticiel ci-dessous devraient, espérons-le, vous aider à démarrer.

Personnalisation des options de phare

L'avantage d'exécuter Lighthouse par programmation n'est pas seulement la possibilité de configurer Lighthouse lui-même, mais plutôt toutes les choses que vous pourriez vouloir ou devoir faire autour des tests Lighthouse. Lighthouse a une excellente documentation pour vous aider à démarrer. Cependant, pour tirer le meilleur parti de son exécution par programmation, vous devrez creuser et en savoir plus sur le fonctionnement de Lighthouse à deux endroits principaux : la configuration de vos exécutions de test et la communication des résultats de vos tests.

Configuration de l'exécution du test Lighthouse

La configuration d'un test Lighthouse fait partie de ces tâches qui peuvent être aussi simples ou aussi complexes que vous le souhaitez.

Lorsque vous exécutez Lighthouse par programmation, vous pouvez fournir des options personnalisées à trois endroits : l'URL que vous allez tester, les options Chrome et l'objet de configuration Lighthouse. Vous pouvez voir que ces trois paramètres sont dans la fonction d'exécution de Lighthouse à partir de la documentation Lighthouse :

 function launchChromeAndRunLighthouse(url, opts, config = null) { return chromeLauncher.launch({chromeFlags: opts.chromeFlags}).then(chrome => { opts.port = chrome.port; return lighthouse(url, opts, config).then(results => { return chrome.kill().then(() => results.lhr) }); }); }

Vous pouvez utiliser le code dont vous avez besoin pour créer ces paramètres. Par exemple, supposons que vous ayez un site avec plusieurs pages ou URL que vous souhaitez tester. Peut-être souhaitez-vous exécuter ce test dans un environnement CI dans le cadre de vos tâches CI, en vérifiant toutes les pages nécessaires à chaque exécution de la tâche. En utilisant cette configuration, vous pouvez utiliser JavaScript pour créer vos URL et créer une boucle qui exécutera Lighthouse pour chacune.

Toutes les options Chrome dont vous pourriez avoir besoin peuvent être spécifiées dans un objet qui est transmis à chrome-launcher. Dans l'exemple de la documentation, l'objet opts contient un tableau que nous appelons chromeFlags que vous pouvez transmettre à chrome-launcher et un port où vous pouvez enregistrer le port utilisé par chrome-launcher, puis le transmettre à Lighthouse.

Enfin, l'objet de configuration Lighthouse vous permet d'ajouter toutes les options spécifiques à Lighthouse. Le package Lighthouse fournit un objet de configuration par défaut qui peut être utilisé tel quel ou étendu et modifié. Vous pouvez utiliser cet objet pour faire une multitude de choses, y compris spécifier les catégories de test Lighthouse que vous souhaitez tester.

Plus après saut! Continuez à lire ci-dessous ↓

Vous pouvez utiliser emulatedFormFactor pour spécifier si vous souhaitez que le test s'exécute dans un émulateur mobile ou de bureau. Vous pouvez utiliser extraHeaders pour ajouter tous les cookies dont vous pourriez avoir besoin dans le navigateur. Par exemple, un test exécutant uniquement la catégorie d'accessibilité sur un émulateur de bureau qui affiche les résultats au format HTML peut avoir un objet de configuration qui ressemble à ceci :

 const lighthouseOptions = { extends: 'lighthouse:default', settings: { onlyCategories: ['accessibility'], emulatedFormFactor:'desktop', output: ['html'], }, }

Cet exemple représente une configuration minimale. Vous pouvez faire beaucoup plus. Les documents de configuration de Lighthouse contiennent beaucoup plus d'informations. Ils ont également un ensemble d'exemples d'objets de configuration pour certaines implémentations plus complexes.

Rapports de résultats personnalisés

Lors de l'exécution de Lighthouse par programme, vous pouvez renvoyer les résultats dans une ou plusieurs des trois options formatées et - et c'est la pièce la plus excitante à mon avis - vous pouvez avoir accès à l'objet brut Lighthouse Result (LHR).

HTML, JSON, CSV

Lighthouse formatera automatiquement les résultats de trois manières différentes : HTML, JSON ou CSV. Ce sont tous des résultats préconfigurés basés sur le modèle de rapport Lighthouse de base, qui est ce que vous voyez si vous exécutez un test Lighthouse dans Chrome DevTools, par exemple. Dans l'objet de configuration lighthouseOptions de la section précédente, vous pouvez voir une clé pour output qui contient un tableau avec une seule chaîne : html . Cela spécifie que je veux uniquement que les résultats soient renvoyés au format HTML. Si je voulais les résultats à la fois en HTML et en JSON, ce tableau ressemblerait à ['html', 'json'] .

Une fois Lighthouse exécuté, il renverra un objet de résultats qui contiendra deux clés : report et lhr . Nous parlerons du contenu de la clé lhr dans la section suivante, mais la clé report contient un tableau avec les résultats formatés comme vous l'avez demandé. Ainsi, par exemple, si nous avons demandé ['html', 'json'] , alors results.report[0] contiendra nos résultats au format HTML et results.report[1] contiendra nos résultats au format JSON.

L'objet LHR

L'exécution de Lighthouse par programmation vous donne également accès à un objet de résultats beaucoup plus flexible : l'objet LHR. Cet objet contient les résultats bruts et certaines métadonnées de votre exécution Lighthouse. Une documentation plus complète peut être trouvée sur le référentiel Lighthouse Github.

Vous pouvez utiliser ces résultats de plusieurs manières, notamment en créant des rapports personnalisés et en collectant des données à partir de plusieurs exécutions à des fins d'analyse.

Exemple : Exécution d'un test d'accessibilité pour mobile et ordinateur de bureau

Disons que j'ai un site qui charge différents composants selon que l'utilisateur utilise un écran plus petit ou plus grand, ce qui signifie que le code HTML de chaque version du site sera légèrement différent. Je veux m'assurer que les deux versions du site obtiennent un score de 95 aux tests d'accessibilité Lighthouse et qu'aucun code ne soit engagé dans notre branche main qui ne réponde pas à cette norme.

Remarque : Si vous souhaitez voir un exemple fonctionnel du code ci-dessous analysant la page d'accueil de Sparkbox, vous pouvez trouver le référentiel ici.

Je peux configurer Lighthouse pour qu'il exécute la catégorie d'accessibilité deux fois, en fournissant différents objets de configuration pour chacun d'entre eux, l'un définissant le emulatedFormFactor sur desktop et l'autre sur mobile . Un moyen simple de le faire est de créer un tableau avec les deux objets, illustré ci-dessous.

 const lighthouseOptionsArray = [ { extends: 'lighthouse:default', settings: { onlyCategories: ['accessibility'], emulatedFormFactor:'desktop', output: ['html', 'json'], }, }, { extends: 'lighthouse:default', settings: { onlyCategories: ['accessibility'], emulatedFormFactor:'mobile', output: ['html', 'json'], }, }, ]

Ensuite, je peux créer une fonction qui parcourra ce tableau et exécutera un test Lighthouse pour chaque objet trouvé dans le tableau.

Une chose à noter est qu'il est nécessaire d'introduire un délai entre chaque exécution, sinon Chromium peut être confus et les exécutions échoueront. Pour ce faire, j'ai ajouté une fonction d' wait qui renvoie une promesse lorsque l'intervalle setTimeout est terminé.

 function wait(val) { return new Promise(resolve => setTimeout(resolve, val)); } function launchLighthouse(optionSet, opts, results) { return chromeLauncher .launch({ chromeFlags: opts.chromeFlags }) .then(async chrome => { opts.port = chrome.port; try { results = await lighthouse(url, opts, optionSet); } catch (e) { console.error("lighthouse", e); } if (results) reportResults(results, runEnvironment, optionSet, chrome); await wait(500); chrome.kill(); }); } async function runLighthouseAnalysis() { let results; const opts = { chromeFlags: ["--no-sandbox", "--headless"] }; for (const optionSet of lighthouseOptionsArray) { console.log("****** Starting Lighthouse analysis ******"); await launchLighthouse(optionSet, opts, results); } }

Dans ce cas, j'envoie les résultats à une fonction reportResults . À partir de là, j'enregistre les résultats dans des fichiers locaux, j'imprime les résultats sur la console et j'envoie les résultats à une fonction qui déterminera si les tests réussissent ou échouent à notre seuil d'accessibilité.

 async function reportResults(results, runEnvironment, optionSet, chrome) { if (results.lhr.runtimeError) { return console.error(results.lhr.runtimeError.message); } await writeLocalFile(results, runEnvironment, optionSet); printResultsToTerminal(results.lhr, optionSet); return passOrFailA11y(results.lhr, optionSet, chrome); }

Pour ce projet, je souhaite pouvoir enregistrer les résultats JSON dans un répertoire spécifié pour nos tests CI et le fichier HTML dans un répertoire spécifié pour nos tests locaux. La façon dont Lighthouse renvoie ces différents types de résultats est dans un tableau dans l'ordre dans lequel ils ont été demandés.

Ainsi, dans cet exemple, dans notre objet lighthouseOptions , notre tableau demande d'abord HTML, puis JSON. Ainsi, le tableau de report contiendra d'abord les résultats au format HTML et ensuite les résultats au format JSON. La fonction writeToLocalFile enregistre alors la version correcte des résultats dans un fichier avec un nom personnalisé.

 function createFileName(optionSet, fileType) { const { emulatedFormFactor } = optionSet.settings; const currentTime = new Date().toISOString().slice(0, 16); const fileExtension = fileType === 'json' ? 'json' : 'html'; return `${currentTime}-${emulatedFormFactor}.${fileExtension}`; } function writeLocalFile(results, runEnvironment, optionSet) { if (results.report) { const fileType = runEnvironment === 'ci' ? 'json' : 'html'; const fileName = createFileName(optionSet, fileType); fs.mkdirSync('reports/accessibility/', { recursive: true }, error => { if (error) console.error('error creating directory', error); }); const printResults = fileType === 'json' ? results.report[1] : results.report[0]; return write(printResults, fileType, `reports/accessibility/${fileName}`).catch(error => console.error(error)); } return null; }

Je souhaite également imprimer les résultats sur le terminal à la fin des tests. Cela fournit un moyen rapide et facile de visualiser les résultats sans avoir à ouvrir un fichier.

 function printResultsToTerminal(results, optionSet) { const title = results.categories.accessibility.title; const score = results.categories.accessibility.score * 100; console.log('\n********************************\n'); console.log(`Options: ${optionSet.settings.emulatedFormFactor}\n`); console.log(`${title}: ${score}`); console.log('\n********************************'); }

Et enfin, je veux pouvoir échouer à mes tests si les scores d'accessibilité n'atteignent pas mon score seuil de 95.

 function passOrFailA11y(results, optionSet, chrome) { const targetA11yScore = 95; const { windowSize } = optionSet; const accessibilityScore = results.categories.accessibility.score * 100; if (accessibilityScore) { if (windowSize === 'desktop') { if (accessibilityScore < targetA11yScore) { console.error(`Target accessibility score: ${targetA11yScore}, current accessibility score ${accessibilityScore}`); chrome.kill(); process.exitCode = 1; } } if (windowSize === 'mobile') { if (accessibilityScore < targetA11yScore) { console.error(`Target accessibility score: ${targetA11yScore}, current accessibility score ${accessibilityScore}`); chrome.kill(); process.exitCode = 1; } } } }

Je vous invite tous à jouer avec et à explorer toutes les différentes façons dont Lighthouse peut vous aider à surveiller la qualité de votre site.

Remarques finales

Bien que j'ai intentionnellement gardé l'exemple ci-dessus relativement simple, j'espère qu'il vous a donné un bon aperçu de ce qui peut être accompli lors de l'exécution de Lighthouse par programme. Et j'espère que cela vous incitera à trouver de nouvelles façons d'utiliser cet outil flexible et puissant.

Comme l'a dit Peter Drucker :

"Si vous ne pouvez pas le mesurer, vous ne pouvez pas l'améliorer."

Pouvoir non seulement mesurer mais surveiller la qualité de notre site Web, en particulier pour les sites complexes, contribuera grandement à nous aider à créer un meilleur Web.

Lectures complémentaires sur SmashingMag :

  • Tests A/B pour les expériences Mobile-First
  • Comment tester l'efficacité d'un concept de design
  • L'importance des tests d'accessibilité manuels
  • Machine Learning pour les développeurs front-end avec Tensorflow.js
  • Commencez avec la conception d'interface utilisateur avec ces conseils pour accélérer votre flux de travail

Le Smashing Cat explore de nouvelles perspectives, aux Smashing Workshops, bien sûr.

Des éléments frontaux et UX utiles, livrés une fois par semaine.

Avec des outils pour vous aider à mieux faire votre travail. Abonnez-vous et recevez les listes de contrôle de conception d'interface intelligente de Vitaly au format PDF par e-mail.

Sur le front-end et l'UX. Reconnu par 190 000 personnes.