Bonjour, je m'appelle Stas Makeev. Chez Yandex, je dirige le développement de la technologie pour les pages Turbo, qui permet un chargement rapide du contenu même avec une connexion lente. Aujourd'hui, je vais parler un peu de l'architecture de notre projet aux lecteurs de Habr.
Le bonheur de l'utilisateur est largement influencé par la rapidité avec laquelle il voit le contenu de la page Web. La vitesse inquiète beaucoup: dans la boutique d'applications mobiles, seul Speedtest compte plus de cent millions d'installations. Les fournisseurs, opérateurs mobiles, développeurs de sites Web et d'applications s'efforcent de fournir l'accès le plus rapide au contenu afin que les clients soient satisfaits.
La vitesse de téléchargement moyenne dans les réseaux mobiles russes est de
16,26 Mbit / s - c'est un très bon indicateur. Mais la vitesse de connexion est inégale, nous sommes toujours confrontés à une connexion Internet lente - 3G, 2G, EDGE. Vous étiez sûrement dans une situation où dans un café ou un centre commercial, sur la route ou à la campagne, la vitesse habituellement élevée est considérablement réduite: les sites se chargent pendant des dizaines de secondes, voire plus.
La technologie Turbo-page résout le problème d'accès au contenu, y compris à des vitesses de connexion faibles ou instables. Ceci est important pour les propriétaires de sites qui ont un pourcentage réduit de visiteurs "tombant" pendant la transition de la recherche.

Comment fonctionnent les pages Turbo
Le propriétaire du site enregistre le flux RSS dans Yandex.Webmaster. Le flux entre dans le système de contenu Turbo Pages, qui prend des mises à jour toutes les quelques minutes. Contenu lourd - principalement des images et des vidéos - que nous mettons en cache et disposons dans un CDN. En plus du RSS, le contenu peut être transmis via l'API et l'autoparser.
Le volume d'images en cache des pages Turbo approche les 100 To
La fiabilité et la tolérance aux pannes du système sont importantes pour nous, c'est pourquoi nous faisons plusieurs répliques des données et les stockons dans nos trois centres de données. Dans chaque centre de données, des centaines de serveurs traitent des milliers de demandes par seconde, ce qui vous permet d'équilibrer la charge de manière flexible.
Le système de contenu Turbo Pages mérite un article séparé, et nous l'écrirons. Pour l'instant, nous nous limitons à un schéma simplifié.

Que se passe-t-il lorsque vous ouvrez une URL dans un navigateur?
Lorsque l'utilisateur accède à la page Turbo, quelque chose comme ce qui suit se produit «sous le capot»:
L'adaptateur HTTP traite la demande HTTP de l'utilisateur et envoie une demande au graphique souhaité dans AppHost et le rapport de rendu.
AppHost est un composant spécial qui encapsule l'interaction réseau des sources, décrit comme un graphique de dépendance. Les sources sont interrogées dans l'ordre de tri topologique sur ce graphe; toute logique métier y est cousue et dans la configuration du graphe. En particulier, au niveau du graphique, le stockage KV est interrogé et une demande de données est envoyée à des API tierces.
Report-renderer est une application écrite en node.js qui accepte les entrées JSON, exécute les modèles écrits en JS et renvoie une chaîne.
Tout cela se produit presque instantanément.
Qu'est-ce qui affecte la vitesse de téléchargement?
Nous travaillons sur tous les aspects de la vitesse: de l'implémentation de HTTP / 2 sur l'équilibreur et l'optimisation de la négociation TLS à l'optimisation manuelle de SVG. Dans ce cas, vous devez comprendre la composition de la vitesse de l'utilisateur final.
Au sein de l'équipe, nous distinguons trois étapes du traitement des demandes: serveur, réseau et client.
ServeurCela inclut tout ce qui se passe dans les centres de données: depuis le moment où la requête HTTP arrive sur notre serveur jusqu'à la génération de la page HTML, qui est envoyée directement au client.
Le temps de traitement des demandes sur le serveur doit être minimal. Malgré les valeurs relativement petites, cela affecte absolument toutes les requêtes des utilisateurs. De plus, tous les processus se produisent dans notre environnement contrôlé - il ne peut tout simplement pas y avoir d'excuses pour des retards importants.
L'heure du serveur est constituée des interactions réseau entre les sommets du graphe de dépendance source et les temps de fonctionnement de chacun des sommets. Mais nous ne nous concentrerons pas sur les caractéristiques de l'infrastructure réseau des centres de données Yandex - ils méritent un article séparé.
Je veux prêter plus d'attention au deuxième composant - le temps d'exécution de chacun des pics. À titre d'exemple, examinons nos principes et outils pour travailler avec le composant Report-renderer, qui est responsable de la génération du HTML. Pour les autres composants, ils sont très similaires.
Dans notre processus CI, certaines tâches acceptent les demandes d'extraction dans dev, qui effectuent des vérifications de base pour chaque validation dans la branche de fonctionnalité. Si des indicateurs dépassent les limites spécifiées, l'influence dans dev est gelée jusqu'à ce que les raisons soient clarifiées.
Mesures clés à ce stade:
- heure du modèle;
- taille de la page récapitulative;
- taille des fichiers statiques.
Nous collectons des statistiques client (CSS et JS) pour chaque page en fonction des données, mais les bundles avec les blocs eux-mêmes sont indépendants de la demande, il suffit donc de comparer la taille des fichiers de la branche avec des fichiers similaires en dev. Pour différents types de fichiers, nous avons défini différentes valeurs de seuil, après quoi la tâche ne peut pas être versée en dev sans "OK" de la part des responsables de la vitesse.
En règle générale, il existe une analyse conjointe du code et recherche des moyens d'optimiser.
Nous devons agir différemment avec les métriques de taille de page et le temps de modèle, car ils dépendent fortement d'une demande spécifique et une sorte de certitude statistique est nécessaire. De plus, vous ne pouvez pas prendre de requêtes synthétiques, car ce seront des mesures malhonnêtes. Par conséquent, nous collectons constamment des demandes d'utilisateurs aléatoires pour les journaux d'accès, en formons des «cartouches» et les «tirons» avec des modèles dans la branche avec des modifications et avec le dev. Cela vous permet de détecter les modifications même sur des demandes peu populaires.
Nous avons plusieurs «paniers de demandes» qui nous permettent de couvrir la majeure partie du trafic vers les pages Turbo.
En plus d'optimiser nos modèles, nous suivons les optimisations qui se produisent dans V8. Par exemple, le passage à
TurboFan a donné d'excellents résultats: le temps de modélisation côté serveur a été considérablement réduit.

Le temps de modélisation du serveur a diminué après le passage à TurboFan
RéseauDans la partie réseau, nous incluons tout ce qui se passe entre le client et le serveur: temps de transfert des données, taille de page et statique, ainsi que la mise en cache des ressources. C'est déjà plus intéressant, car à partir de nos centres de données confortables, nous nous trouvons dans le monde extérieur sauvage, où tout ne dépend pas de nous. Les mesures deviennent un peu plus compliquées, et surtout - vous pouvez obtenir des résultats vraiment tangibles en centaines de millisecondes.
Voici ce que nous faisons.
Nous avons tordu les paramètres TCP et TLS, qui vous permettent de gagner plusieurs RTT (Round Trip Time), cela donne d'excellents résultats dans les réseaux à latence élevée. Nos collègues ont déjà
écrit à ce sujet, donc je ne vais pas approfondir.
La taille des données transmises peut grandement affecter la vitesse de téléchargement, nous essayons donc d'envoyer uniquement ce dont la page actuelle a besoin de la manière la plus efficace.
Les images de nos interfaces sont optimisées à l'aide d'ImageOptim. Pour optimiser SVG, nous utilisons non seulement
SVGO , mais nous ne sommes pas trop paresseux pour examiner le contenu et, si possible, l'optimiser à la main.
Nous téléchargeons des images des propriétaires de sites vers un CDN spécial, optimisé pour le rendu d'images. Nous recadrons le profil exif et couleur de l'image en convertissant d'abord l'image en sRGB. Le débit binaire est réduit à 8 bits par canal, le niveau de compression est réglé à 85. Le filtre lanczos est utilisé pour le redimensionnement.
Nous créons des dizaines d'options pour chaque image pour une combinaison de différentes tailles d'écran, en tenant compte de la densité de pixels (écrans rétine). Et bien sûr, nous encodons automatiquement les images au format WebP, si elles sont prises en charge par le navigateur.
Les formats de texte (HTML, JavaScript, CSS) sont compressés à l'aide de gzip / zopfli et brotli, si le navigateur le prend en charge.
Il est important de ne pas oublier l'éloignement des utilisateurs des serveurs. Les pages turbo sont utilisées dans de nombreuses régions et le contenu peut être quelconque. Nous ne faisons donc aucun compromis et pour réduire la latence même dans les régions les plus reculées, nous utilisons CDN, qui est en constante expansion.
Et bien sûr, la requête la plus rapide est qu'ils ne le font pas du tout. Toutes les statistiques sont fournies avec une mise en cache éternelle à partir d'un domaine séparé sans cookies, et pour augmenter le cache, il peut encore être réchauffé en plus sur la page principale et la page avec les résultats de la recherche.
ClientIl ne suffit pas de former une réponse du serveur et de la transmettre au navigateur via le réseau, elle doit encore être affichée efficacement. Nous optimisons l'heure de début du rendu de la page afin que la personne commence à lire le contenu plus rapidement.
Dans l'en-tête HTML, nous «réchauffons» la connexion à nos serveurs de distribution statiques et la préchargons également. Styles intégrés à la page, ce qui permet au navigateur de commencer à afficher la page sans attendre le chargement des styles sur le réseau.
Les images de contenu, les incorporations et les publicités ne sont pas chargées immédiatement, mais au fur et à mesure qu'elles lisent la page, lorsqu'elles se rapprochent du champ de vision de l'utilisateur.
JavaScript est partiellement intégré dans HTML et tous les autres scripts sont chargés à la fin avec des requêtes HTTP distinctes. Les scripts essentiels au démarrage, la collecte des erreurs et des métriques, ainsi que les composants qui ne sont pas souvent trouvés sur la page sont intégrés dans la page.
Nous collectons des métriques de chargement de page RUM. Le plus critique: le temps jusqu'au premier octet, le premier dessin et le début de l'interactivité, lorsque tous les scripts ont terminé l'initialisation et que l'utilisateur peut utiliser la page.
La plupart des utilisateurs n'accèdent pas directement aux pages Turbo, mais à partir d'autres services Yandex, et nous voulions évaluer le temps de chargement des pages dans le contexte de l'expérience utilisateur. Non seulement obtenir un temps abstrait dans le vide, mais une mesure de la façon dont l'utilisateur voit tout.
Nous avons donc formulé la métrique de vitesse intégrale:
max (firstContentfulPaint, firstImageLoadTime, timeToVisible) — timeToClick
Où:
- timeToClick - temps de clic absolu qui a conduit à l'affichage de la page Turbo. Cela peut être un clic sur un extrait de la page de résultats de recherche ou sur une carte dans Yandex.Zen.
- firstImageLoadTime - temps de chargement absolu de la première image de contenu dans le premier écran.
- timeToVisible - le temps absolu où la page entre dans l'état visible. Cela est vrai pour les cas où la page a été chargée en arrière-plan.
Et obtenu une métrique d'expérience utilisateur:
- si 2/3 de l'écran est occupé par une image qui n'a pas encore été chargée, l'intégrité de la première métriqueContentfulPaint est plutôt douteuse;
- il y a beaucoup de gestionnaires d'événements sur les liens, entre le clic et l'heure de début réelle du chargement de la page, une heure non nulle pourrait passer, ce que j'aimerais comprendre.

Nous développons constamment des technologies afin que les sites attirent plus de visiteurs. Désormais, une page Turbo se charge en moyenne 15 fois plus rapidement qu'une version mobile standard. Des dizaines de milliers de sites utilisent Turbo et le nombre total de visites sur ces sites dépasse les 12 milliards.
Tout cela est le résultat du travail des développeurs, des services d'assistance, des gestionnaires travaillant avec les propriétaires de sites et bien d'autres. Au fil du temps, l'équipe, bien sûr, s'agrandit. Par exemple, nous recherchons maintenant des
spécialistes du frontend et du backend et nous serons heureux de voir de nouveaux collègues.
Quels composants de la technologie Turbo Page aimeriez-vous lire à l'avenir des documents techniques plus détaillés? Quelle expérience vous intéresserait? Nous accueillerons également les commentaires et les idées. Je vous remercie!