Cas pratique d'optimisation approfondie H5 : Comment optimiser et faire évoluer l'architecture du mobile QQ Hybrid ? Titre original : Plus de 70 % de l'activité est développée par H5. Comment optimiser et faire évoluer l'architecture du mobile QQ Hybrid
Avec l'essor du développement front-end, QQ a progressivement évolué vers un modèle de développement qui combine Web et terminaux natifs. Tout en bénéficiant des capacités de fonctionnement dynamique du Web, QQ a également été confronté à davantage de défis en termes de vitesse de réponse interactive, de pression de service en arrière-plan et d'impact sur la bande passante d'un ensemble massif d'utilisateurs. Face au rythme rapide des opérations Web, il est nécessaire de garantir que les services tiers intégrés dans QQ soient toujours dans un état de service de haute qualité. En réponse à ces problèmes, l'équipe QQ utilise non seulement des méthodes full-stack telles que le CDN dynamique et le rendu en arrière-plan pour optimiser l'expérience, mais construit également un système de surveillance axé sur la vitesse, le taux de réussite, les exceptions de page et d'autres dimensions pour garantir la qualité du service. .
Tout d'abord, présentez-vous, je m'appelle Tu Qiang. J'ai rejoint Tencent en 2005. A cette époque, le développement mobile et hybride n'était pas encore populaire. Je développais principalement la version PC de QQ. Plus tard, lorsque j'étais responsable de la version PC du moteur QQ UI, j'ai fait quelques tentatives pour intégrer le noyau du navigateur sur le client PC. À cette époque, j'en ai fait quelques . frameworks de développement mixte H5 et natif 🎜>Travail du sexe. Après cela, j'ai rejoint l'équipe des membres de Tencent QQ et j'étais responsable de la technologie des membres QQ sur les terminaux mobiles. En même temps, j'avais également une tâche très ardue : maintenir tous les frameworks de développement hybrides H5 dans QQ mobile, c'est-à-dire le. travail technique du composant WebView.
Pour en revenir au sujet, l'hybride grand public actuel est toujours H5 + natif. Il n'est pas nécessaire de mentionner l'importance du développement du H5 pour les terminaux mobiles actuels, mais tout le monde peut voir les problèmes évidents du H5 en natif, tels que. lors de l'ouverture de l'application. La page qui attend depuis longtemps son chargement est susceptible d'être perdue lorsque l'utilisateur voit l'interface chrysanthème lors du chargement. C'est également une situation que le chef de produit ne souhaite pas voir. Un autre point est que chaque fois que vous ouvrez H5, cela implique une interaction réseau et untéléchargement de fichiers. Ces opérations consommeront du trafic de l'utilisateur. Si la consommation de trafic est importante, l'utilisateur sera mécontent.
Le contenu que je partagerai avec vous aujourd'hui présente principalement comment l'équipe des membres de QQ a optimisé le temps d'ouverture de la page et le trafic des utilisateurs, correspondant respectivement aux deux cadres techniques indépendants de sonic et reshape.JSON, afin d'accélérer ce processus, localStroage peut être utilisé pour la mise en cache L'ensemble de ce processus est un processus de chargement de page statique très traditionnel, qui. est relativement simple.
Mais la solution ci-dessus présente quelques problèmes. Par exemple, lorsque nous lançons WebView, le réseau est dans un état inactif, ce qui fait perdre du temps. Selon les statistiques internes de notre équipe, il faut moins d'une seconde pour lancer WebView sur une machineAndroid (car le téléphone mobile QQ a une architecture multi-processus, et WebView vit dans une autre Le lancement de WebView une fois s'ajoute au chargement du processus. Il y a également le chargement du noyau du navigateur).
Deuxièmement, les pages statiques publiées sur CDN ne contiennent pas de données d'élément, donc lorsque les utilisateurs voient pour la première fois la page téléchargée à partir de CDN, la zone de bannière et la zone d'élément sont vides, ce qui nuit également à l'expérience utilisateur. dommage. Il y a un autre problème. Lors du chargement de la page, vous devez actualiser le DOM actuel, c'est-à-dire extraire le JSON, puis diviser la structure du DOM, puis actualiser. Nous avons constaté cela sur les machines Android bas de gamme. Utilisée par certains utilisateurs de QQ, cette exécution prendra également beaucoup de temps.Face à ces problèmes, nous avons audacieusement adopté certains moyens techniques, que nous appelons le modèle de sortie directe statique + pré-push hors ligne. Tout d'abord, nous avons parallélisé le chargement de WebView et la requête réseau. Toutes nos requêtes réseau n'ont pas été initiées à partir du noyau WebView, mais pendant le processus de chargement de WebView, nous avons établi notre propre lien HTTP via le canal natif, puis l'avons connecté. avec nous depuis le CDN La page est obtenue à partir d'un endroit appelé OfflineServer. Ce serveur hors ligne est également la stratégie de mise en cache des packages hors ligne dont tout le monde a entendu parler.
Nous aurons unCache hors ligne en natif. Lors du lancement d'une requête HTTP, nous vérifions d'abord s'il y a un cache HTML actuel dans le cache hors ligne. Ce cache est isolé du cache WebView et le sera. ne pas être affecté par WebView. L'impact des politiques de mise en cache est entièrement sous notre contrôle.
S'il n'y a pas de cache dans OfflineCache, il ira sur OfflineServer pour synchroniser les fichiers, et il téléchargera également les mises à jour depuis le CDN. Le HTML que nous stockons sur le CDN a déjà saisi toutes les données telles que la bannière et l'élément dans la page statique. À ce stade, tant que WebView obtient le HTML, il n'a pas besoin d'actualiser ou d'exécuter du JS pour la page entière. peut être affiché directement et l'utilisateur peut interagir.
Cette solution permettra d'abord d'économiser le temps de lancement de WebView. Pendant ce temps, elle pourra être directement transmise sur le réseau. De plus, s'il existe un cache hors ligne localement, il n'y a pas besoin de demande de transmission réseau, ce qui équivaut à un chargement complet d'une page locale. Mais souvent, par mesure de sécurité, nous ajoutons le chargement de pages, puis effectuons des opérations d'actualisation pour éviter toute incohérence des données.
Ce mécanisme fonctionne bien une fois mis en ligne, mais si vous implémentez vraiment ce mode de chargement H5, vous rencontrerez quelques écueils, comme l'image de bannière configurée par le chef de produitLes données des tranches et des articles peuvent avoir plusieurs versions de données incohérentes.
Le chef de produit doit avoir configuré les dernières informations de données sur le serveur de données, mais les données intégrées à la page sur le CDN peuvent toujours être dans la version précédente. Ce qui est encore pire, c'est que le serveur de packages hors ligne et le HTML. générés par offlineServer sont une version différente. Un problème courant d'actualisation du cache se produit lorsque le cache local et le serveur de l'utilisateur ne sont pas synchronisés, et il est très probable que les données stockées soient une autre copie.
Ainsi, lorsque l'essai en niveaux de gris de ce système a commencé, le chef de produit est rapidement venu nous voir pour se plaindre : lorsque vous ouvrez la page, vous voyez une donnée. le contenu que vous voyez après avoir actualisé la page est différent, et cela se produit chaque fois que vous entrez dans la page.
Comment unifier rapidement les quatre versions des données ? Nous avons construit un petit système de construction automatique pour le mode de sortie directe statique. Lorsque le chef de produit configure les données côté gestion pour synchroniser le serveur de données, nous démarrerons immédiatement notre système de construction interne appelé vnues.
Ce système est construit sur la base de Node.js Il générera la dernière version de HTML en temps réel à partir des fichiers de code et des matériaux d'interface utilisateur images écrits par le. développeurs, puis publiez-le sur CDN et synchronisez-le avec offlineServer, ce qui peut résoudre le problème d'incohérence entre les fichiers CDN et les dernières données.
Mais le cache du package hors ligne est placé sur le téléphone mobile de l'utilisateur. Comment pouvons-nous mettre à jour le cache hors ligne sur le téléphone mobile de l'utilisateur le plus rapidement possible ? Vous pouvez faire ceci : chaque fois que vous vous connectez au client QQ, téléchargez simplement les derniers fichiers depuis le serveur hors ligne. Cependant, cette solution rencontrera d'énormes problèmes de trafic.
QQ compte désormais des centaines de millions d'utilisateurs actifs chaque jour, avec des connexions maximales de près de centaines de milliers par seconde. Même une mise à jour de package hors ligne de 100 Ko nécessitera des centaines de Go de bande passante pour être publiée, tant en termes de coût. et la technologie. Ce ne sont pas des choses que nous pouvons accepter.
Notre serveur hors ligne est divisé en deux parties : le contrôle de flux et le calcul hors ligne. Lorsque toutes les ressources d'une page doivent être empaquetées pour le calcul du paquet hors ligne, en plus d'empaqueter toutes les ressources, la partie de calcul hors ligne stockera également en interne toutes les versions historiques précédentes et générera en même temps tous les d en fonction de l'historique. version et la dernière version iff, c'est-à-dire la différence entre chaque package hors ligne.
Ce plan est également basé sur notre formulaire commercial, car les données de page mises à jour à chaque fois par le chef de produit ne sont pas de trop, essentiellement de l'ordre de quelques Ko à 10+ Ko, nous n'avons donc pas besoin pour se déconnecter à chaque fois que les mises à jour du package nécessitent que les utilisateurs téléchargent le package complet.
Lorsqu'un utilisateur QQ se connecte , il sera demandé à chaque fois au serveur de contrôle de flux hors ligne de voir s'il existe le dernier package pouvant être téléchargé. Si la bande passante comptée par le serveur de contrôle de flux actuel est égale. à un coût acceptable (actuellement provisoirement 10 Go à 20 Go d'espace), lorsque la bande passante du CDN peut être maintenue, la dernière différence sera envoyée au client, de sorte que lorsque le package hors ligne est mis à jour, le client puisse être actualisé au moment opportun. coût de trafic minimum.
Grâce à ce système, nous n'avons dépensé que plus de dix Go de bande passante pour posséder l'intégralité de BG Le hors ligne Le taux de couverture des forfaits de l'activité H5 se maintient autour de 80 à 90 %. À partir de ce travail, nous avons également découvert une chose très non conventionnelle, c'est-à-dire que tout le monde pense que le pré-push de paquets hors ligne consomme beaucoup de bande passante, mais en fait, le pré-push ne consomme qu'occasionnellement beaucoup de bande passante s'il est poussé en continu pour beaucoup ; années, il consomme en fait beaucoup de bande passante, très faible, car il est constamment maintenu dans un état de distribution différentielle.
Après avoir effectué ce travail, nous avons collecté les données du réseau en direct. Le contraste entre les deux modes d'exportation directe statique et de page traditionnelle est très évident. En ce qui concerne la partie fastidieuse de la page dans la figure ci-dessous, étant donné que la page de sortie directe statique ne nécessite aucune exécution JS et nécessite uniquement un rendu WebView, le temps de sortie directe statique de la page est réduit d'environ 500 millisecondes à environ 1. seconde par rapport à la page traditionnelle.
Le phénomène intéressant ici est la rentabilité des packages hors ligne. On peut voir que l'utilisation de packages hors ligne sur des pages traditionnelles peut économiser plus de 700 millisecondes dans le temps réseau. consommant une partie, mais de manière statique. L'utilisation de packages hors ligne dans ce mode ne permet d'économiser qu'environ 300 millisecondes. En effet, les CSS et JS externes sur lesquels s'appuie l'exportation statique pendant le processus réseau ont déjà été exportés vers le. à l'intérieur du HTML, et aucune demande de réseau supplémentaire n'est requise, donc le temps de réseau lui-même est réduit. À ce stade, les avantages de l'utilisation de packages hors ligne commencent à diminuer progressivement.
Vous avez peut-être des questions ici : pourquoi le temps de réseau sortant statique prend-il plus de 800 millisecondes dans le cas de paquets hors ligne ? Ne devrait-il pas être nul s'il existe un cache local ?
Le temps réseau que nous estimons est le temps écoulé entre le début de l'URL de chargement de WebView et la première ligne de la page, ce qui inclut en fait le chargement d'une pagination , le démarrage de la Noyau WebView, composants réseau et rendu Le chargement des composants est relativement long.
Il y a certainement place à l'optimisation ici, mais lorsque notre équipe client était sur le point d'optimiser la partie chronophage du réseau, la forme de notre entreprise a changé. Dans le passé, le chef de produit affichait n'importe quelle page qu'il configurait et tous les utilisateurs voyaient le même contenu. Désormais, le chef de produit dit que chaque utilisateur devrait voir un contenu complètement différent lorsqu'il accède à la page d'accueil du centre commercial.
L'image suivante est un exemple. Le contenu de la page d'accueil de gauche est recommandé de manière aléatoire, tandis que le contenu de droite est en fait envoyé via l'apprentissage automatique en fonction des Comportements Les habitudes sont calculées et mises en correspondance avec les éléments de notre backend, contenu recommandé en fonction des préférences et du comportement de l'utilisateur.
Chaque utilisateur entre et voit un contenu différent, donc le modèle statique direct ne fonctionnera pas car nous ne pouvons pas mettre toutes les pages des utilisateurs dans Il est généré dans l'arrière-plan puis envoyé au CDN. Cependant, il existe un moyen très simple de résoudre ce modèle.Lorsque l'utilisateur entre dans la page pour la deuxième fois, sonicBridge donnera la priorité à la soumission de la page mise en cache localement à WebView. L'utilisateur peut voir le contenu sans attendre la demande du réseau lors de la saisie. la page. C’est bon pour l’utilisateur. L’amélioration de l’expérience en termes de vitesse est relativement importante, mais cela introduit un autre problème.
En fait, le contenu que les utilisateurs voient est différent à chaque fois qu'ils ouvrent WebView. Les données renvoyées par Node.js sont les plus récentes à chaque fois. Par conséquent, nous devons laisser WebView recharger les données extraites, ce qui donne à l'utilisateur. L'expérience est la suivante : j'ai évidemment ouvert le code HTML mis en cache localement et vu le contenu, mais la page entière est rechargée dès que je l'utilise. Le rechargement de WebView prend beaucoup de temps sur certains modèles bas de gamme. Les utilisateurs peuvent clairement sentir que la page WebView H5 entière reste vide pendant un certain temps, puis que le nouveau contenu est actualisé.
Combiné avec l'expérience mentionnée précédemment d'accès direct statique à la partie de rafraîchissement partiel du DOM, nous pouvons réduire la quantité de transmission réseau et la quantité de données soumises à la page. La première chose que nous faisons est de réduire la quantité de transmission sur le réseau et d’éviter une actualisation trop tardive.
Nous avons modifié le protocole HTML du groupe Node.js Lorsque sonicBridge demande des données pour la deuxième fois, le serveur Node.js ne répondra pas à l'intégralité. Le HTML est renvoyé à SonicBridge, mais la partie que nous appelons data est renvoyée.
Après avoir obtenu les données, nous avons conclu un accord avec la page H5. Le côté natif appellera la fonction de rafraîchissement fixe de la page et transmettra les données à la page. La page actualisera partiellement son propre nœud DOM, de sorte que même si la page doit être actualisée, la page entière ne sera pas rechargée.
Spécifiquement à partir du processus de contenu des données, la première page de chargement de SonicBridge renvoie toujours du HTML complet, et en même temps, l'identifiant que nous appelons template-tag est renvoyé ce modèle. -tag marquera la partie statique et inchangée de la valeur hash dans cette page. Cette mesure sert à contrôler la mise en cache. Nous aurons également quelques balises dans le code HTML renvoyé, telles que sonicdiff-banner. Cette bannière détermine son identifiant d'actualisation.
Lors du deuxième chargement, les données renvoyées ne contiennent pas l'intégralité du HTML vu précédemment, et seulement environ 37 Ko de données seront renvoyées. Ces données sont en fait un JSON. , mais il définit la structure DOM correspondant à l'exemple précédent sonicdiff-banner. Afin de sauvegarder le code exécuté dans H5, nous épelons directement le code du nœud DOM en JSON, de sorte que la page n'ait besoin que de faire correspondre et actualiser les identifiants.
Il est difficile d'éviter les données de transmission de 37 Ko ici. Nous avons observé que la quantité de données actualisées est différente selon les services. Pouvons-nous réduire la quantité de données soumises à la page pour actualisation ? Après tout, le chef de produit ne modifie pas beaucoup de données à chaque fois ?
En plus de ce qui est mentionné précédemment, nous mettrons en cache le HTML complet et le modèle au niveau de la couche sonicCache, et extrairons également les données pour créer dataCache .
Lorsque le modèle est accédé pour la première fois, il supprime toutes les données variables et supprime le cadre de page restant en fonction des informations d'identification dans sonicdiff. Lorsque l'utilisateur l'ouvre pour la deuxième fois, il lui suffit de fusionner les données renvoyées avec le modèle localement sur le client pour obtenir le code HTML complet.
Après avoir mis en cache chaque dataCache, nous faisons également une différence dans les données. Par exemple, cette fois, la requête a renvoyé 37 Ko de données, et les dernières données mises en cache étaient également de 37 Ko. .de données, nous déterminerons la quantité réellement modifiée en interne, puis donnerons uniquement la différence à l'actualisation HTML. Dans la plupart des scénarios, notre page n'a besoin que de traiter environ 9 Ko de données pour actualiser la page entière.
Grâce au cache, les utilisateurs peuvent l'ouvrir localement très rapidement. La transmission de données différentielles réduit également le temps d'actualisation et d'attente des utilisateurs. Enfin, ce type de soumission de données. est ajouté. La comparaison fastidieuse réduit considérablement la plage d'actualisation de la page.
L'ensemble du processus du mode sonique est le suivant. Cela semble compliqué, mais le principe de base est de mettre en cache le modèle HTML et les données demandées via Bridge.
Vous avez peut-être des questions ici. Les stratégies de serveur hors ligne et de pré-push hors ligne pour lesquelles j'ai consacré beaucoup d'efforts à apparaître statiquement plus tôt sont-elles toujours utiles ici ? En fait, nous utilisons toujours le mécanisme de mise en cache hors ligne pour les pages dynamiques et les pages statiques mentionné précédemment, car nos pages professionnelles ont également beaucoup de JS publics, comme le package JS API fourni par QQ, et certains partagés. CSS également pré-publié via la stratégie de package hors ligne, c'est également ce que tout le monde téléchargera à chaque fois qu'il se connectera.
Après avoir terminé ce mode, l'effet des données est relativement évident. Les performances du premier chargement et du chargement HTTP ordinaire sont similaires, mais la deuxième fois, l'utilisateur. ouvre la page À ce stade, cela ne prend généralement qu'une seconde pour voir la page. Cette seconde inclut également la surcharge du processus de lancement du client et de WebView. En même temps, notre vitesse de chargement n'est plus affectée par l'environnement réseau de l'utilisateur. , qu'il s'agisse de la vitesse de chargement 2G ou 4G. Tous sont proches de la même chose.
Et cela apporte également un avantage. Si le réseau de l'utilisateur est relativement pauvre, comme des tremblements fréquents et une incapacité à se connecter, parce que nous avons un cache local, notre page peut être ouverte même si l'utilisateur est actuellement déconnecté.
Aucun scénario de mise à jour du modèle n'est mentionné ici. La mise à jour du modèle signifie que le modèle que nous extrayons peut changer dynamiquement sur notre serveur. Le processus de chargement à ce moment est différent de ce que nous avons mentionné précédemment, lorsque le modèle change. suivez toujours le processus original de rechargement de la page HTML. La consommation de temps ici est relativement élevée, mais nos statistiques révèlent que la plupart des utilisateurs tombent toujours dans l'état de rafraîchissement des données, c'est-à-dire la deuxième ouverture.
Lors de l'optimisation de l'accélération H5, il est facile pour tout le monde de se demander si nous doit utiliser des connexions persistantes. Évitez les accès fastidieux à la connexion du serveur, au DNS, à la prise de contact, etc. Les clients comme QQ ont une connexion persistante avec le serveur backend. Si vous utilisez cette connexion pour demander un fichier HTML au serveur backend et le transmettre à WebView, cela sera-t-il plus rapide que d'établir temporairement une demande de connexion ? Il nous suffit de configurer un service proxy inverse pour accéder à notre serveur Node.js à partir du backend de messages QQ. Ce processus peut être résolu, mais nous évaluons que ce modèle peut ne pas convenir à tous les scénarios.
Il est vrai que certaines applications utilisent le canal de connexion persistante pour charger des pages, mais il est difficile de le faire sur QQ mobile car le canal de connexion persistante entre le client QQ mobile et le serveur est une architecture CS très traditionnelle . Il envoie un package socket. Chaque fois qu'il doit envoyer un package de requête, il passera à la requête suivante après avoir reçu la réponse.
Ce mécanisme de réponse détermine qu'il nécessite un processus d'attente à chaque fois, et les contraintes du package de socket font que la taille de chaque paquet de données transmis est limitée, comme nos 30+ The KB les données sont susceptibles d'être divisées en cinq ou six paquets de données. Bien que la connexion persistante soit utilisée pour économiser le temps de connexion, de multiples communications aller-retour avec le serveur augmentent la consommation de temps globale.
De plus, les données renvoyées par le serveur Node.js sont en streaming HTTP. WebView n'a pas besoin d'attendre que l'intégralité du HTML soit chargée avant de pouvoir être rendue et affichée tant qu'elle est lancée. obtient le premier octet de la transmissionDocument, analyse et construction DOM.
Si nous souhaitons utiliser des connexions persistantes, nous devrons probablement passer par des étapes telles que le cryptage, le déchiffrement et l'empaquetage côté client, et nous devrons attendre que l'intégralité du téléchargement HTML soit terminée avant de pouvoir le faire. peut être affiché. Nous pensons que ce temps ralentira les performances.
Après l'introduction ci-dessus, vous aurez peut-être une impression approximative et intuitive de QQHybrid : 1. Nous sommes ici Les étudiants en développement front-end de WebScope ont effectué une partie du travail : 2. Nos étudiants en développement de terminaux de couche native ont effectué le pontage, et 3. Nos étudiants back-end ont fait beaucoup d'intégration automatique et de push du serveur hors ligne. La structure de cette partie est la suivante :
Ensuite, je présenterai la partie sur le trafic des pages sur le côté droit du diagramme d'architecture. Nous avons compté la répartition du trafic dans chaque entreprise. Comme le montre la figure ci-dessous, nous pouvons clairement voir que la majeure partie du trafic est consommée sur les ressources d'images. Cependant, lorsque nous avons effectué cette analyse, nous avions également des doutes quant à la détermination des caractéristiques de l'entreprise. notre consommation d’image. Le plus ? Est-ce également vrai pour les autres services H5 de QQ Mobile ?
Nous avons eu l'occasion lors de la Fête du Printemps 2016, Mobile QQ a organisé un événement auquel presque toutes les entreprises ont participé - Fête du Printemps Rouge. Enveloppes. Vous vous souvenez peut-être encore de la pratique consistant à appuyer constamment sur l'écran pour recevoir des enveloppes rouges lors de la soirée de la Fête du Printemps en 2016. Ce type de carnaval national a entraîné une énorme pression de trafic. Environ 300 000 paquets cadeaux sont distribués aux utilisateurs chaque seconde. Le trafic Web qui guide les utilisateurs ouvrira des centaines de milliers de pages H5 chaque seconde. On estimait à l'époque que les pics de trafic dépassaient 1 To.
Nous avons analysé le trafic d'images, et en effet il représente près de la moitié. Pour certaines d'entre elles, nous avons utilisé le pré-push de packages hors ligne pour les envoyer en amont sur les téléphones portables des utilisateurs, mais pendant l'événement, les images sur le réseau étaient Le trafic est toujours supérieur à 200 Go.
Le trafic n'est pas un problème qui peut être résolu en payant simplement de l'argent à l'opérateur. Lors des activités de la Fête du Printemps, nous avons failli rencontrer une situation où le trafic sous un seul nom de domaine était proche de 200 Go. , l’architecture CDN n’en pouvait plus.
Nous pensons tous qu'il existe un grand potentiel ici. Si le trafic d'images peut être économisé, les coûts de bande passante peuvent être réduits. Le trafic réseau et la consommation de la batterie du téléphone portable du côté de l'utilisateur peuvent être meilleurs, c'est pourquoi notre équipe a vérifié de nouvelles choses concernant les formats d'image.
Tout le monde connaît WebP, et Android le prend mieux en charge. L'équipe QQ a développé en interne un format d'image appelé SharpP. économisé d'environ 10 % par rapport à WebP. Ce qui suit est une comparaison des données extraites des images existantes sur notre serveur CDN.
La taille de l'image est dominante, mais qu'en est-il de la vitesse de décodage ? Nous avons utilisé respectivement des modèles haut de gamme, milieu de gamme et bas de gamme pour l'analyse. Malheureusement, SharpP est effectivement un peu plus lent que WebP ou même JPG. Mais heureusement, la taille de l'image de notre entreprise n'est pas trop grande. des dollars de plus sur la page sont également acceptables, et nous pensons que c'est plus avantageux que de gagner du temps en attendant le réseau.
Nous prévoyons donc de promouvoir le format SharpP dans le secteur mobile QQ H5, mais la promotion du nouveau format d'image entraînera des coûts d'application énormes. Tout d’abord, la plupart des liens images sont codés en dur, et la page ne sait pas si le terminal mobile a la capacité de décoder le format SharpP.
La page H5 doit-elle préparer un HTML différent pour les différentes versions mobiles de QQ ? Ou lorsque des ressources d'images sont publiées sur CDN, deux liens dans des formats différents sont générés, puis différents liens sont sélectionnés en fonction de la version du terminal dans H5 ? Ce coût de développement est certainement inacceptable.
En plus des problèmes de format d'image, nous avons constaté que différents modèles d'utilisateurs gaspilleront du trafic. Notre conception d'interface utilisateur est généralement conçue pour la taille de l'écran de l'iPhone6 et la valeur par défaut est un matériau d'image de 750 px. Les téléphones mobiles dotés de petits écrans, tels que 640 px et 480 px, téléchargent également des images de 750 px, puis les réduisent lors du rendu.
Cela gaspille en fait beaucoup de bande passante, nous réfléchissons donc à savoir si CDN peut fournir des images dans différents formats en fonction de la taille de l'écran du téléphone mobile de l'utilisateur.
Cette stratégie d'adaptation à l'écran se heurte également au coût d'un format quasi privé, car le CDN ne connaît pas la situation du téléphone portable. Enfin, nous avons proposé l'architecture de remodelage, qui peut être grossièrement divisée en 4 niveaux à partir du lien complet de téléchargement d'images :
Nous appelons le site source CDN de couche inférieure, nous avons déployé ici un outil de conversion de format d'image. Le côté commercial n'a pas besoin de se soucier de la production JPG avant de générer SharpP ou WebP. Il lui suffit de publier l'image sur le site source CDN pour la convertir automatiquement. au format et à la résolution d'écran correspondants.
Ci-dessus se trouvent les nœuds CDN auxquels les téléphones mobiles des utilisateurs accèdent, déployant des serveurs à travers le pays pour accélérer et mettre en cache les fichiers.
Nous avons coopéré avec l'équipe du navigateur pour mettre le format de décodage SharpP dans le cœur du navigateur, afin que l'entreprise de haut niveau n'ait pas besoin de se soucier de savoir si le navigateur actuel prend en charge WebP ou SharpP. .
Lorsque la page est ouverte, WebView apportera automatiquement la taille de l'écran du terminal et les formats d'image pris en charge au nœud CDN. Le nœud CDN obtient alors les dernières images de l'origine. site Le site d'origine est celui-ci. L'image correspondante peut avoir été générée hors ligne ou en temps réel.
Démontez la couche WebView. En plus d'intégrer la bibliothèque de décodage SharpP, d'autres choses sont relativement simples, comme :
Demande de head. Des champs supplémentaires sont ajoutés à er, par exemple, "Pixel/750" est ajouté à User-Agent S'il s'agit d'une machine de 480 pixels, la valeur devient 480 ;
.Ajout de l'en-tête du protocole SharpP dans Accepter : image/sharpP
stockera 3 dans le site d'origine *3 numéro de photos. Lorsque chaque photo d'entreprise est soumise au site source pour publication, 9 photos seront générées. Le nœud CDN demandera le type d'image correspondant au site d'origine CDN selon la demande de WebView, mais pour le business et WebView, la demande est toujours le même lien, de sorte que toutes les pages H5 de Mobile QQ n'ont besoin d'aucune ligne du front end En modifiant le code, vous pouvez profiter de l'adaptation de taille et des économies de trafic apportées par le format d'image.
Ce qui suit est un processus plus vivant, ajoutez des champs dans Accepter, puis renvoyez l'image correspondante :
Cette technologie n'est pas compliquée, personnellement, je ne pense pas qu'il y ait un seuil technique profond, il s'agit plutôt d'ouvrir toute la chaîne depuis le client, le Web jusqu'au backend CDN. Mais nous avons également rencontré quelques écueils dans le processus : lorsque nous travaillions en niveaux de gris, nous avons constaté que de nombreux utilisateurs iOS se plaignaient du fait que les images ne pouvaient pas s'afficher lorsque la page était affichée.
Cela nous a surpris car cette technologie n'avait pas encore été déployée sur iOS, uniquement sur Android. Nous avons vérifié le code CDN et il n'y a aucun problème, alors pourquoi les images SharpP sont-elles distribuées aux utilisateurs iOS ?
Une analyse ultérieure a révélé que les opérateurs de différentes régions de Chine fourniraient des services de mise en cache similaires à CDN Cache. Lorsqu'un utilisateur Android demande une image SharpP pour la première fois, le serveur de l'opérateur obtient le lien au format SharpP depuis notre CDN. Lorsque d'autres utilisateurs iOS de la même région font des requêtes pendant la période de validité du cache, l'opérateur constate que l'URL est la même et renvoie directement l'image au format SharpP à l'utilisateur iOS.
Ce problème est un écueil dans notre architecture globale car nous n'avons pas procédé à un examen complet. HTTP a une convention standard pour résoudre ce problème de mise en cache. Lorsque CDN distribue du contenu, lorsque vous spécifiez le cache via le champ Vary, vous devez vous référer aux champs Accept et User-Agent. Après avoir ajouté ce Vary, le problème est fondamentalement résolu.
Cette affaire nous donne une inspiration supplémentaire. Dans notre réseau actuel, le champ Pixel a trois valeurs : 480px, 640px et 750px. Nous avons discuté en interne de la possibilité d'écrire la taille de l'écran directement dans le User-Agent, de sorte que lorsque Android proposera de nouvelles résolutions d'écran, nous pourrons également effectuer une meilleure adaptation en arrière-plan et générer différents formats pour chaque image de modèle.
Si nous faisons cela, cela entraînera d'énormes frais de retour à l'origine pour l'opérateur et notre propre cache CDN. Chaque image de résolution doit être mise en cache, par exemple 498px. Si l'opérateur intermédiaire ne dispose pas du cache pour ce modèle, il ira vers notre service pour revenir à la source de cette façon, N tailles d'écran apporteront N fois le retour à. notre pression de source CDN.
Pour en revenir au sujet, l'effet final des données est également assez évident. L'image ci-dessous représente nos données d'effet en niveaux de gris Android. Le trafic d'images de notre activité H5 est passé de 40+ Go à 20+ Go. Pour Tencent, plus de 20 Go de bande passante ne représentent pas un coût particulièrement important, mais dans le scénario de la Fête du Printemps, cela peut presque doubler l'espace commercial. Un avantage supplémentaire est que le temps d’attente des utilisateurs pour voir les images des pages est relativement réduit et que le trafic côté utilisateur est également réduit de moitié.
Lorsque nous avons résolu le problème de la vitesse de chargement des pages et de la consommation de trafic, nous avons également commencé à considérez-le Problèmes de stabilité du H5 en fonctionnement rapide. Je pense que les développeurs front-end ont tous rencontré des situations où une fois le code d'une certaine page modifié, d'autres fonctions ne fonctionneront pas correctement. Lors de l'utilisation du développement hybride, il est très probable que le natif fournisse de nombreuses API pour les pages JS. De petits changements côté client peuvent affecter l'API JS, entraînant un fonctionnement anormal des pages H5 sur l'ensemble du réseau.
En plus de la stabilité fonctionnelle, il y a un autre gros problème. Nous publions des pages front-end tous les jours, alors comment ne pas dégrader les performances d'optimisation de la page ? Nous avons finalement passé du temps à réduire les performances de chargement de la page à 1 seconde. Y aura-t-il des modifications frontales telles que l'introduction de davantage de dépendances JS/CSS de liens externes qui dégraderont les performances de la page entière ? Nous avons créé quelques outils pour résoudre ces problèmes.
C'est ce que nous appelons en interne l'automatisation des tests rapides. Nous écrirons tous les ensembles de scénarios de test sur le front-end sous forme de tests automatisés, puis exécuterons chaque jour tous les ensembles de scénarios de test sur toutes les pages de l'ensemble du réseau pour vérifier si les fonctions sont normales.
Nous surveillerons les performances du Web avec le test de performance Web La première chose que nous observons ici est à chaque fois que la page est consultée. est ouvert. Le trafic consommé, nous utiliserons donc des outils pour analyser toutes les images chargées sur la page pour voir si certaines d'entre elles peuvent être converties en SharpP mais utilisent toujours JPG. Grâce à cet ensemble de surveillance, les développeurs H5 extérieurs à notre équipe peuvent être invités à optimiser leurs pages.
Le front-end mentionne souvent la nécessité de réduire le nombre de requêtes lors de l'optimisation, etc. Celles-ci peuvent être considérées comme des règles militaires, et nous les superviserons lors des tests. Nous n'avons pas mentionné en détail certaines méthodes d'optimisation côté client auparavant, mais nous avons également effectué un suivi du temps nécessaire au démarrage de WebView sur le client.
Nous avons également un processus de publication front-end plus strict, tous écrits et testés dans le environnement de test Le code réussi doit réussir la vérification QTA et WPT s'il doit être publié dans l'environnement formel. Si le taux de réussite du test automatisé est inférieur à 95 %, sa publication n'est pas autorisée.
Après avoir été publiés dans l'environnement officiel, nous disposons également d'un système complet de surveillance des scores sur le réseau externe. Le principal indicateur de surveillance est la vitesse. Nous décomposons la vitesse d'ouverture des pages en consommation de temps client et consommation de temps réseau. et la consommation de temps de page et les surveiller séparément.
Nous publierons chaque jour le rapport de surveillance suivant pour observer les changements de vitesse quotidiens. Ici, nous ne sommes pas simplement préoccupés par les performances de. sur l'ensemble du réseau, nous sommes plus préoccupés par l'expérience des utilisateurs lents, comme la récente proportion d'utilisateurs avec plus de 5 secondes.
En plus de cela, H5 rencontre souvent certaines erreurs JS qui provoquent des anomalies de la page, un chargement lent qui fait que l'utilisateur voit un écran blanc trop longtemps, etc. Nous en effectuons un suivi systématique.
En plus de ce qui a été mentionné précédemment, nous avons également construit une plateforme de débogage, beaucoup de débogage La fonctionnalité a été déployée à l'avance dans tous les terminaux mobiles QQ. Nous pouvons utiliser des commandes à distance pour vérifier la résolution DNS de l'utilisateur, quel serveur a été touché, si l'utilisateur a été piraté par l'opérateur, etc.
L'ensemble de l'architecture QQHybrid est essentiellement présentée. En plus de l'optimisation des performances, nous optimisons également le CDN. La structure a été ajustée et des outils de suivi opérationnel ont également été développés. Je pense que c'est le système de surveillance des opérations qui permet à l'ensemble de nos équipes H5 et hybird de modifier avec audace les pages et de publier de nouvelles fonctionnalités tout en garantissant stabilité et fiabilité.
L'ensemble du processus nous a également fait sentir que l'architecture hybride n'est pas comme tout le monde l'avait compris auparavant. Elle fonctionne bien lorsque le client et le front-end travaillent ensemble. système d'architecture, la technologie backend joue également un rôle important. Nous avons également demandé le soutien de l'équipe d'exploitation et de maintenance pour la transformation du CDN, et l'équipe de test et de développement a également participé à QTA et WPT. On peut dire que la mise en place de l’ensemble du système est le résultat du travail côte à côte de toutes les positions.
Articles connexes recommandés :
Parcours d'apprentissage du front-end Web : introduction rapide au développement front-end WEB