Comment nous avons amélioré nos éléments vitaux Web de base (étude de cas)
L'année dernière, Google a commencé à souligner l'importance de Core Web Vitals et comment ils reflètent l'expérience réelle d'une personne lors de la visite de sites sur le Web. La performance est une caractéristique fondamentale de notre entreprise, Recherche instantanée de domaine – c'est dans le nom. Imaginez notre surprise lorsque nous avons constaté que nos scores vitaux n'étaient pas excellents pour beaucoup de gens. Nos ordinateurs rapides et notre Internet par fibre ont masqué l'expérience des personnes réelles sur notre site. Il ne fallut pas longtemps avant qu'une mer d'avertissements rouges "pauvres" et jaunes "à améliorer" dans notre console de recherche Google retiennent notre attention. Entropy avait gagné, et nous devions trouver comment nettoyer le jank et rendre notre site plus rapide.

J'ai fondé Instant Domain Search en 2005 et je l'ai gardé comme une activité secondaire pendant que je travaillais dans une entreprise de Y Combinator (Snipshot, W06), avant de travailler comme ingénieur logiciel chez Facebook . Nous sommes récemment devenus un petit groupe basé principalement à Victoria, au Canada, et nous travaillons sur un long arriéré de nouvelles fonctionnalités et d’améliorations des performances. Nos faibles scores Web Vitals et la imminente mise à jour de Google nous ont amenés à trouver et à résoudre ces problèmes.
Lorsque la première version du site a été lancée, je l'avais construite avec PHP, MySQL et XMLHttpRequest . Internet Explorer 6 était entièrement pris en charge, Firefox gagnait des parts et Chrome était encore à des années de son lancement. Au fil du temps, nous avons évolué grâce à une variété de générateurs de sites statiques, de frameworks JavaScript et de technologies de serveur. Notre pile frontale actuelle est React servie avec Next.js et un service backend intégré à Rust pour répondre à nos recherches de noms de domaine. Nous essayons de suivre les meilleures pratiques en servant autant que possible sur un CDN, en évitant autant de scripts tiers que possible et en utilisant de simples graphiques SVG au lieu de fichiers PNG bitmap. Ce n’était pas assez.
Next.js nous permet de créer nos pages et nos composants en React et TypeScript. Lorsqu'il est associé à VS Code, l'expérience de développement est incroyable. Next.js fonctionne généralement en transformant les composants React en HTML et CSS statiques. De cette façon, le contenu initial peut être servi à partir d'un CDN, puis Next peut «hydrater» la page pour rendre les éléments dynamiques. Une fois la page hydratée, notre site se transforme en une application d'une seule page où les gens peuvent rechercher et générer des noms de domaine. Nous ne comptons pas sur Next.js pour faire beaucoup de travail côté serveur, la majorité de notre contenu est exporté statiquement au format HTML, CSS et JavaScript pour être servi à partir d'un CDN.
Quand quelqu'un démarre à la recherche d'un nom de domaine, nous remplaçons le contenu de la page par les résultats de la recherche. Pour rendre les recherches aussi rapides que possible, le front-end interroge directement notre backend Rust qui est fortement optimisé pour les recherches et suggestions de domaine. De nombreuses requêtes auxquelles nous pouvons répondre instantanément, mais pour certains TLD, nous devons effectuer des requêtes DNS plus lentes qui peuvent prendre une seconde ou deux à résoudre. Lorsque certaines de ces requêtes plus lentes seront résolues, nous mettrons à jour l'interface utilisateur avec les nouvelles informations. Les pages de résultats sont différentes pour tout le monde, et il peut être difficile pour nous de prédire exactement comment chaque personne vit le site.
The Chrome Les DevTools sont excellents et constituent un bon point de départ pour rechercher des problèmes de performances. La vue Performances montre exactement quand les requêtes HTTP sont envoyées, où le navigateur passe du temps à évaluer JavaScript, etc.:

Il existe trois métriques Core Web Vitals que Google utilisera pour aider à classer les sites dans leur prochaine mise à jour de leur algorithme de recherche . Google classe les expériences en "Bon", "Besoin d'amélioration" et "Faible" en fonction des scores LCP, FID et CLS que de vraies personnes ont sur le site:
- LCP ou Largest Contentful Paint, définit l'heure il faut pour que le plus grand élément de contenu devienne visible.
- FID ou First Input Delay, se rapporte à la réactivité d'un site à l'interaction – le temps entre un tap, un clic ou une pression sur une touche dans l'interface et la réponse du page.
- CLS ou Cumulative Layout Shift, suit la façon dont les éléments se déplacent ou se déplacent sur la page en l'absence d'actions comme un événement de clavier ou de clic.

Chrome est configuré pour suivre ces métriques pour tous les utilisateurs Chrome connectés et renvoie des statistiques anonymes résumant l'expérience d'un client sur un site à Google pour évaluation. Ces scores sont accessibles via le Rapport d'expérience utilisateur Chrome et s'affichent lorsque vous inspectez une URL avec l'outil PageSpeed Insights . Les scores représentent l'expérience du 75e centile des personnes qui ont visité cette URL au cours des 28 derniers jours. C'est le nombre qu'ils utiliseront pour aider à classer les sites dans la mise à jour.
Une métrique du 75e centile (p75) atteint un équilibre raisonnable pour les objectifs de performance. Prendre une moyenne de par exemple, cacherait beaucoup de mauvaises expériences vécues par les gens. La médiane ou 50e percentile (p50), signifierait que la moitié des personnes utilisant notre produit vivaient une pire expérience. Le 95e percentile (p95), en revanche, est difficile à construire car il capture trop de valeurs extrêmes sur les anciens appareils avec des connexions irrégulières. Nous pensons que la notation basée sur le 75e centile est une norme juste à respecter.

Pour maîtriser nos scores, nous nous sommes d'abord tournés vers Lighthouse pour un excellent outil intégré à Chrome et hébergé sur web.dev/measure/ et sur PageSpeed Insights . Ces outils nous ont aidés à trouver des problèmes techniques généraux avec notre site. Nous avons vu que la façon dont Next.js regroupait notre CSS et ralentissait notre temps de rendu initial, ce qui affectait notre FID. La première victoire facile est venue d'une fonctionnalité expérimentale de Next.js, OptimizeCss qui a contribué à améliorer considérablement notre score de performances générales.
Lighthouse a également détecté une erreur de configuration du cache qui a empêché la diffusion de certains de nos actifs statiques. notre CDN. Nous sommes hébergés sur Google Cloud Platform et le CDN Google Cloud exige que l'en-tête Cache-Control contienne «public» . Next.js ne vous permet pas de configurer tous les en-têtes qu'il émet, nous avons donc dû les remplacer en plaçant le serveur Next.js derrière Caddy un serveur proxy HTTP léger implémenté dans Go. Nous avons également profité de l'occasion pour nous assurer que nous servions ce que nous pouvions avec le support relativement nouveau stale-while-revalidate dans les navigateurs modernes qui permet au CDN d'extraire le contenu de l'origine (notre serveur Next.js) de manière asynchrone en arrière-plan.
Il est facile – peut-être trop facile – d'ajouter presque tout ce dont vous avez besoin à votre produit à partir de npm . Il ne faut pas longtemps pour que la taille des lots augmente. Les gros lots prennent plus de temps à télécharger sur des réseaux lents, et le téléphone mobile du 75e centile passera beaucoup de temps à bloquer le thread principal de l'interface utilisateur tout en essayant de comprendre tout le code qu'il vient de télécharger. Nous avons aimé BundlePhobia qui est un outil gratuit qui montre combien de dépendances et d'octets un paquet npm ajoutera à votre paquet. Cela nous a conduit à éliminer ou à remplacer un certain nombre d'animations alimentées par react-spring par des transitions CSS plus simples:

Grâce à l'utilisation de BundlePhobia et de Lighthouse, nous avons constaté que les logiciels tiers de journalisation et d'analyse des erreurs contribuaient de manière significative à la taille de notre bundle et au temps de chargement. Nous avons supprimé et remplacé ces outils par notre propre journalisation côté client qui tire parti des API de navigateur modernes telles que sendBeacon et ping . Nous envoyons la journalisation et l'analyse à notre propre infrastructure Google BigQuery où nous pouvons répondre aux questions qui nous intéressent plus en détail que n'importe quel outil standard. Cela élimine également un certain nombre de cookies tiers et nous donne beaucoup plus de contrôle sur la manière et le moment où nous envoyons les données de journalisation des clients.
Notre score CLS avait encore le plus de marge d'amélioration. La façon dont Google calcule CLS est compliquée: vous disposez d'une "fenêtre de session" maximale avec un intervalle d'une seconde, plafonnée à 5 secondes à partir du chargement initial de la page, ou à partir d'un clavier ou d'une interaction par clic, pour terminer le déplacement des éléments sur le site. . Si vous souhaitez approfondir ce sujet, voici un excellent guide sur le sujet. Cela pénalise de nombreux types de superpositions et de popups qui apparaissent juste après avoir atterri sur un site. Par exemple, les annonces qui déplacent le contenu ou les ventes incitatives qui peuvent apparaître lorsque vous commencez à faire défiler les annonces pour atteindre le contenu. Cet article fournit une excellente explication de la façon dont le score CLS est calculé et du raisonnement qui le sous-tend.
Nous sommes fondamentalement opposés à ce type de fouillis numérique et nous avons donc été surpris de voir à quel point Google peut être amélioré. insisté pour que nous fassions. Chrome possède une superposition Web Vitals intégrée à laquelle vous pouvez accéder en utilisant le menu de commande pour «Afficher la superposition Core Web Vitals». Pour voir exactement quels éléments Chrome prend en compte dans son calcul CLS, nous avons trouvé l'option "Consignation de console" de Chrome Web Vitals extension dans les paramètres plus utile. Une fois activé, ce plugin affiche vos scores LCP, FID et CLS pour la page en cours. Depuis la console, vous pouvez voir exactement quels éléments de la page sont connectés à ces scores. Nos scores CLS avaient le plus de possibilités d'amélioration.

Des trois métriques, CLS est la seule qui s'accumule lorsque vous interagissez avec une page. L'extension Web Vitals a une option de journalisation qui montrera exactement quels éléments causent CLS pendant que vous interagissez avec un produit. Regardez comment les métriques CLS s'ajoutent lorsque nous faisons défiler la page d'accueil de Smashing Magazine:
Google continuera à ajuster la façon dont il calcule CLS au fil du temps, il est donc important de rester informé en suivant le blog de développement Web de Google . Lorsque vous utilisez des outils tels que l'extension Chrome Web Vitals, il est important d'activer la régulation du processeur et du réseau pour obtenir une expérience plus réaliste. Vous pouvez le faire avec les outils de développement en simulant un processeur mobile .

La meilleure façon de suivre la progression d'un déploiement à l'autre est de mesurer les expériences de page de la même manière que Google. Si Google Analytics est configuré, un moyen simple de le faire consiste à installer le module web-vitals de Google et à le connecter à Google Analytics . Cela fournit une mesure approximative de votre progression et la rend visible dans un tableau de bord Google Analytics.

C'est là que nous avons heurté un mur. Nous pouvions voir notre score CLS, et même si nous l'avions amélioré de manière significative, nous avions encore du travail à faire. Notre score CLS était d'environ 0,23 et nous devions l'obtenir en dessous de 0,1 – et de préférence jusqu'à 0. À ce stade, cependant, nous n'avons pas pu trouver quelque chose qui nous indiquait exactement quels composants sur quelles pages affectaient encore le score. Nous avons pu voir que Chrome a exposé beaucoup de détails dans leurs outils Core Web Vitals, mais que les agrégateurs de journalisation ont jeté la partie la plus importante: quel élément de page exactement a causé le problème.

Pour capturer tous les détails dont nous avons besoin, nous avons créé une fonction sans serveur pour capturer les données Web Vitals à partir des navigateurs. Comme nous n'avons pas besoin d'exécuter des requêtes en temps réel sur les données, nous les diffusons dans l'API de streaming de Google BigQuery pour le stockage. Cette architecture signifie que nous pouvons capturer à peu de frais autant de points de données que nous pouvons générer.
Après avoir appris quelques leçons tout en travaillant avec Web Vitals et BigQuery, nous avons décidé de regrouper cette fonctionnalité et de publier ces outils en open-source à l'adresse ] vitals.dev .
L'utilisation de Instant Vitals est un moyen rapide de commencer à suivre vos scores Web Vitals dans BigQuery. Voici un exemple de schéma de table BigQuery que nous créons:

L'intégration à Instant Vitals est facile. Vous pouvez commencer en vous intégrant à la bibliothèque cliente pour envoyer des données à votre fonction backend ou sans serveur:
import {init} depuis "@ instantdomain / vitals-client";
init ({endpoint: "/ api / web-vitals"});
Ensuite, sur votre serveur, vous pouvez intégrer à la bibliothèque du serveur pour compléter le circuit:
import fs from "fs";
import {init, streamVitals} depuis "@ instantdomain / vitals-server";
// Les bibliothèques Google nécessitent une clé de service comme chemin d'accès au fichier
const GOOGLE_SERVICE_KEY = process.env.GOOGLE_SERVICE_KEY;
process.env.GOOGLE_APPLICATION_CREDENTIALS = "/ tmp / goog_creds";
fs.writeFileSync (
process.env.GOOGLE_APPLICATION_CREDENTIALS,
GOOGLE_SERVICE_KEY
);
const DATASET_ID = "web_vitals";
init ({datasetId: DATASET_ID}). then (). catch (console.error);
// Gestionnaire de requêtes
export async par défaut (req, res) => {
const body = JSON.parse (req.body);
attendre streamVitals (corps, corps.nom);
res.status (200) .end ();
};
Appelez simplement streamVitals
avec le corps de la requête et le nom de la métrique pour envoyer la métrique à BigQuery. La bibliothèque se chargera de la création de l'ensemble de données et des tables pour vous.
Après avoir collecté une journée de données, nous avons exécuté cette requête comme celle-ci:
SELECT
« .web_vitals.CLS» .Valeur,
Nœud
DE
« .web_vitals.CLS»
REJOINDRE
UNNEST (Entrées) AS Entry
REJOINDRE
UNNEST (Entry.Sources)
OÙ
Nœud! = ""
COMMANDÉ PAR
valeur
LIMITE
dix
Cette requête produit les résultats suivants:
Value | Node |
---|---|
4.6045324800736724E-4 | / html / body / div [1] / main / div / div / div [2] / div /div/blockquote[19659063letter7183070668914928E-4[19659062[/html/body/div[19459143[/header/div/div/header/div[19659063unity)0031002668277977697[19659062Oftml/body/div[19459143unitypieddepage |
0,035830703317463526 | / html / body / div [1] / main / div / div / div [2] |
0,035830703317463526 | / html / body / div [1] / footer |
0,03582630 | / html / body / div [1] / main / div / div / div [2] |
0.035830703317463526 | / html / body / div [1] / main / div / div / div [2] |
0.035830703317463526 | / html / body / div [1] / footer |
0.035830703317463526 | / html / body / div [1] / footer |
0.03988482067913317 | / ht body [1] / footer |
Ceci nous montre quels éléments sur quelles pages ont le plus d'impact sur CLS. Il a créé une liste de poinçons que notre équipe doit étudier et corriger. Sur la recherche instantanée de domaine, il s'avère que les connexions mobiles lentes ou défectueuses prendront plus de 500 ms pour charger certains de nos résultats de recherche. L'un des pires contributeurs à CLS pour ces utilisateurs était en fait notre pied de page.
Le score de décalage de mise en page est calculé en fonction de la taille de l'élément en mouvement et de sa distance. Dans notre vue des résultats de recherche, si un appareil prend plus d'un certain temps pour recevoir et afficher les résultats de la recherche, la vue des résultats se réduirait à une hauteur nulle
faisant apparaître le pied de page. Lorsque les résultats arrivent, ils repoussent le pied de page vers le bas de la page. Un grand élément DOM qui se déplaçait jusque-là a beaucoup ajouté à notre score CLS. Pour résoudre ce problème correctement, nous devons restructurer la façon dont les résultats de la recherche sont collectés et rendus. Nous avons décidé de supprimer simplement le pied de page dans la vue des résultats de recherche comme un piratage rapide qui l'empêcherait de rebondir sur des connexions lentes.
Nous examinons maintenant ce rapport régulièrement pour suivre comment nous nous améliorons – et l'utiliser pour lutter contre le déclin résultats à mesure que nous avançons. Nous avons constaté la valeur d'une attention particulière aux fonctionnalités et produits nouvellement lancés sur notre site et avons opérationnalisé des contrôles cohérents pour nous assurer que les éléments vitaux essentiels agissent en faveur de notre classement. Nous espérons qu'en partageant Instant Vitals nous pourrons également aider d'autres développeurs à s'attaquer à leurs scores Core Web Vitals.
Google fournit d'excellents outils de performance intégrés à Chrome, et nous les avons utilisés pour trouver et corriger un certain nombre de performances questions. Nous avons appris que les données de terrain fournies par Google offraient un bon résumé de nos progrès p75, mais ne contenaient pas de détails exploitables. Nous devions savoir exactement quels éléments DOM causaient des changements de disposition et des retards d'entrée. Une fois que nous avons commencé à collecter nos propres données de terrain (avec des requêtes XPath), nous avons pu identifier des opportunités spécifiques pour améliorer l'expérience de chacun sur notre site. Avec quelques efforts, nous avons ramené nos scores de champ Core Web Vitals réels dans une fourchette acceptable en vue de la mise à jour de l'expérience de page de juin. Nous sommes heureux de voir ces chiffres descendre et vers la droite!


Source link