Heim >Schlagzeilen >Praktischer Fall zur detaillierten h5-Optimierung: Wie kann die Architektur des mobilen QQ Hybrid optimiert und weiterentwickelt werden?
Praktischer Fall der ausführlichen H5-Optimierung: Wie kann die Architektur des mobilen QQ Hybrid optimiert und weiterentwickelt werden? Originaltitel: Mehr als 70 % des Geschäfts werden von H5 entwickelt. Wie kann die Architektur des mobilen QQ Hybrid optimiert und weiterentwickelt werden? ein Entwicklungsmodell, das Web- und native Terminals kombiniert. Während QQ die dynamischen Betriebsfunktionen des Webs nutzte, stand es auch vor größeren Herausforderungen in Bezug auf die Geschwindigkeit der interaktiven Reaktion, den Druck auf Hintergrunddienste und die Auswirkungen einer großen Benutzergruppe auf die Bandbreite. Angesichts der rasanten Geschwindigkeit des Webbetriebs muss sichergestellt werden, dass sich die in QQ eingebetteten Dienste Dritter stets in einem hochqualitativen Dienstzustand befinden. Als Reaktion auf diese Probleme nutzt das QQ-Team nicht nur Full-Stack-Methoden wie dynamisches CDN und Hintergrund-Rendering, um das Erlebnis zu optimieren, sondern baut auch ein Überwachungssystem auf, das sich auf Geschwindigkeit, Erfolgsquote, Seitenausnahmen und andere Dimensionen konzentriert, um die Servicequalität sicherzustellen .
Schreiben Sie es vorne auf
Trennung von dynamischen und statischen Seiten in traditionellen Seiten
Alle Technologieauswahlen und Frameworks müssen basierend auf der Geschäftsform ausgewählt werden. Möglicherweise haben Sie ein einfaches Verständnis des Geschäfts Form von QQ-Mitgliedern lernen. Man kann sagen, dass mehr als 70 % des Geschäfts im mobilen QQ von H5 entwickelt werden, beispielsweise das Haupt-Einkaufszentrum für Mitglieder: Spieleverteilungszentrum, Mitgliederprivilegien-Zentrum und das personalisierte Business-Einkaufszentrum, für das ich derzeit verantwortlich bin usw. Die Merkmale dieser Einkaufszentren sind offensichtlich. Es handelt sich nicht um von UGC generierte Seiten, sondern um Inhalte, die vom Produktmanager im Hintergrund konfiguriert werden, beispielsweise die Emoticons und Themen, die auf der Seite angezeigt werden.Der Prozess hier ist ungefähr wie folgt: Der Benutzer beginnt mit dem Klicken, startet WebView und WebView lädt die HTML-Datei auf das CDN. Es wird
JSONabgerufen. Um diesen Prozess zu beschleunigen, kann localStroage für das Caching
verwendet werden. Dieser gesamte Prozess ist ein sehr traditionellerstatischer Seitenladevorgang , was relativ einfach ist. Aber die obige Lösung weist einige Probleme auf. Wenn wir beispielsweise WebView starten, befindet sich das Netzwerk in einem Leerlaufzustand, was Zeit verschwendet. Laut internen Statistiken unseres Teams dauert es weniger als 1 Sekunde, WebView auf einem
Android-Rechner zu starten (da das QQ-Mobiltelefon über eine Multiprozess--Architektur
verfügt und WebView auf einem anderen Rechner läuft). Der einmalige Start von WebView erfolgt zusätzlich zum Laden des Prozesses.Zweitens enthalten statische Seiten, die auf CDN veröffentlicht werden, keine Artikeldaten. Wenn Benutzer also die vom CDN heruntergeladene Seite zum ersten Mal sehen, sind der Bannerbereich und der Artikelbereich leer, was sich ebenfalls stark nachteilig auf die Benutzererfahrung auswirkt Schaden. Es gibt ein weiteres Problem. Beim Laden der Seite müssen Sie das aktuelle DOM aktualisieren, das heißt, die DOM-Struktur zusammenfügen und dann aktualisieren Diese Ausführung wird von einigen QQ-Benutzern verwendet und ist sehr zeitaufwändig.
Angesichts dieser Probleme haben wir mutig einige technische Mittel eingeführt, die wir als statische Direktausgabe + Offline-Pre-Push-Modell bezeichnen. Zunächst haben wir das Laden von WebView und die Netzwerkanforderung parallelisiert. Alle unsere Netzwerkanforderungen wurden nicht vom WebView-Kern initiiert, sondern während des Ladevorgangs von WebView haben wir unseren eigenen HTTP-Link über den nativen Kanal eingerichtet und ihn dann verbunden bei uns vom CDN Die Seite wird von einem Ort namens offlineServer bezogen. Dieser offlineServer ist auch die Offline-Paket-Caching-Strategie, von der jeder gehört hat.
Wir werden einen Offline-Cache in nativer Form haben. Beim Initiieren einer HTTP-Anfrage prüfen wir zunächst, ob ein aktueller HTML-Cache im Offline-Cache vorhanden ist werden von der WebView nicht beeinflusst. Die Auswirkungen der Caching-Richtlinien unterliegen vollständig unserer Kontrolle.
Wenn im offlineCache kein Cache vorhanden ist, wird es zum OfflineServer weitergeleitet, um Dateien zu synchronisieren, und es werden auch Updates vom CDN heruntergeladen. Der HTML-Code, den wir im CDN speichern, hat bereits alle Daten wie Banner und Elemente in die statische Seite eingegeben. Solange WebView den HTML-Code erhält, muss die gesamte Seite nicht aktualisiert oder ausgeführt werden können direkt angezeigt werden und der Benutzer kann interagieren.
Diese Lösung spart zunächst die Zeit, in der WebView gestartet wird. In dieser Zeit kann es außerdem direkt über das Netzwerk übertragen werden, wenn lokal ein Offline-Cache vorhanden ist. Es ist keine Netzwerkübertragungsanforderung erforderlich, was einem vollständigen Laden einer lokalen Seite entspricht. Um auf der sicheren Seite zu sein, fügen wir jedoch häufig das Laden von Seiten hinzu und führen dann Aktualisierungsvorgänge durch, um Dateninkonsistenzen zu vermeiden.
Dieser Mechanismus funktioniert gut, nachdem er online geht, aber wenn Sie diesen H5-Lademodus wirklich implementieren, werden Sie auf einige Fallstricke stoßen, wie zum Beispiel das Bannerbild, das von konfiguriert wurde der ProduktmanagerSlice- und Artikeldaten können mehrere Datenversionen haben, die inkonsistent sind.
Der Produktmanager muss die neuesten Dateninformationen auf dem dataServer konfiguriert haben, aber die in die Seite auf dem CDN integrierten Daten befinden sich möglicherweise noch in der vorherigen Version. Noch schlimmer ist, dass der Offline-Paketserver und der HTML-Code vorhanden sind Die von offlineServer generierten Versionen sind unterschiedlich. Ein häufiges Problem bei der Cache-Aktualisierung tritt auf, wenn der lokale Cache und der Server des Benutzers nicht synchron sind und es sehr wahrscheinlich ist, dass es sich bei den gespeicherten Daten um eine weitere Kopie handelt.
Als der Graustufentest dieses Systems begann, kam der Produktmanager schnell zu uns, um sich zu beschweren: Wenn Sie die Seite öffnen, sehen Sie ein Datenelement Der Inhalt, den Sie nach dem Aktualisieren der Seite sehen, ist anders, und dies geschieht jedes Mal, wenn Sie die Seite aufrufen.
Wie vereinheitlicht man schnell alle vier Datenversionen? Wir haben ein kleines automatisches Build-System für den statischen Direct-Out-Modus erstellt. Wenn der Produktmanager die Daten auf der Verwaltungsseite konfiguriert, um den dataServer zu synchronisieren, starten wir sofort unser internes Build-System namens vnues.
Dieses System basiert auf Node.js. Es generiert die neueste Version von HTML in Echtzeit aus den von ihm geschriebenen Codedateien und UI-Materialien Bildern Entwickler, und veröffentlichen Sie es dann im CDN und synchronisieren Sie es mit offlineServer, wodurch das Problem der Inkonsistenz zwischen CDN-Dateien und den neuesten Daten gelöst werden kann.
Aber der Offline-Paketcache wird auf dem Mobiltelefon des Benutzers abgelegt. Wie können wir den Offline-Cache auf dem Mobiltelefon des Benutzers so schnell wie möglich aktualisieren? Sie können Folgendes tun: Laden Sie jedes Mal, wenn Sie sich beim QQ-Client anmelden, einfach die neuesten Dateien vom Offline-Server herunter. Diese Lösung stößt jedoch auf große Datenverkehrsprobleme.
QQ hat jetzt jeden Tag Hunderte Millionen aktive Benutzer, mit Spitzenanmeldungen von fast Hunderttausenden pro Sekunde. Selbst ein 100-KB-Offline-Paket-Update erfordert für die Veröffentlichung Hunderte von GB Bandbreite, sowohl was die Kosten angeht und Technologie. Das sind Dinge, die wir nicht akzeptieren können.
Unser OfflineServer ist in zwei Teile gegliedert: Flusskontrolle und Offline-Berechnung. Wenn alle Ressourcen einer Seite für die Offline-Paketberechnung gepackt werden müssen, speichert der Offline-Berechnungsteil zusätzlich zum Packen aller Ressourcen auch alle vorherigen historischen Versionen intern und generiert gleichzeitig alle d basierend auf den historischen Versionen Version und die neueste Version, wennf, also der Differenzteil jedes Offline-Pakets.
Dieser Plan basiert auch auf unserem Geschäftsformular, da die vom Produktmanager jedes Mal aktualisierten Seitendaten nicht zu groß sind, grundsätzlich im Bereich von einigen KB bis 10+ KB, sodass wir sie nicht benötigen um jedes Mal offline zu gehen. Bei Paketaktualisierungen müssen Benutzer das vollständige Paket herunterladen.
Wenn sich ein QQ -Benutzer anmeldet , wird der Offline-Flusskontrollserver jedes Mal gefragt, ob das neueste Paket zum Herunterladen verfügbar ist, wenn die vom aktuellen Flusskontrollserver gezählte Bandbreite bei liegt akzeptable Kosten (derzeit vorläufig auf 10 GB bis 20 GB Speicherplatz festgelegt), wenn die Bandbreite des CDN aufrechterhalten werden kann, wird das neueste Diff an den Client gesendet, sodass der Client bei der Aktualisierung des Offline-Pakets aktualisiert werden kann die minimalen Verkehrskosten.
Durch dieses System haben wir nur mehr als zehn GB Bandbreite ausgegeben, um das gesamte BG The offline zu besitzen Die Paketabdeckungsrate des H5-Geschäfts liegt weiterhin bei etwa 80 % bis 90 %. Bei dieser Arbeit haben wir auch eine sehr unkonventionelle Sache entdeckt: Jeder denkt, dass Offline-Paket-Pre-Push viel Bandbreite verbraucht, aber tatsächlich verbraucht nur gelegentliches Pre-Push viel Bandbreite, wenn es kontinuierlich gepusht wird Viele Jahre lang verbraucht es tatsächlich viel Bandbreite. Es ist sehr klein, da es ständig in einem Zustand der Differenzverteilung gehalten wird.
Nach Abschluss dieser Arbeit haben wir die Live-Netzwerkdaten gesammelt. Der Kontrast zwischen den beiden Modi des statischen Direktexports und der herkömmlichen Seite ist sehr offensichtlich. Was den zeitaufwändigen Teil der Seite in der folgenden Abbildung betrifft: Da die statische Direct-Out-Seite keine JS-Ausführung erfordert und nur WebView-Rendering erfordert, wird der zeitaufwändige statische Direct-Out der Seite um etwa 500 Millisekunden reduziert etwa 1 Sekunde im Vergleich zur herkömmlichen Seite.
Das interessante Phänomen hierbei ist die Kosteneffizienz von Offline-Paketen. Es zeigt sich, dass durch die Verwendung von Offline-Paketen auf herkömmlichen Seiten mehr als 700 Millisekunden an Netzwerkzeit eingespart werden können. verbrauchender Teil, aber statisch aus diesem Modus. Durch die Verwendung von Offline-Paketen in diesem Modus können nur etwa 300 Millisekunden eingespart werden. Dies liegt daran, dass das externe CSS und JS, auf das der statische Export während des Netzwerkprozesses angewiesen ist, bereits in das exportiert wurde Innerhalb von HTML ist keine zusätzliche Netzwerkanforderung erforderlich, sodass die Netzwerkzeit selbst reduziert wird. Zu diesem Zeitpunkt beginnen die Vorteile der Verwendung von Offline-Paketen allmählich abzunehmen.
Möglicherweise haben Sie hier Fragen: Warum dauert die statische ausgehende Netzwerkzeit bei Offline-Paketen nicht mehr als 800 Millisekunden, wenn ein lokaler Cache vorhanden ist?
Die von uns geschätzte Netzwerkzeit ist die Zeit vom Start der WebView-Lade-URL bis zur ersten Zeile der Seite, die tatsächlich das Laden einer Paging-Seite und den Start der Seite umfasst WebView-Kernel, Netzwerkkomponenten und Rendering Das Laden von Komponenten ist relativ zeitaufwändig.
Hier gibt es definitiv Raum für Optimierungen, aber als unser Kundenteam den zeitaufwändigen Teil des Netzwerks optimieren wollte, änderte sich unsere Geschäftsform. Früher zeigte der Produktmanager die von ihm konfigurierte Seite an und alle Benutzer sahen den gleichen Inhalt. Jetzt sagt der Produktmanager, dass jeder Benutzer völlig unterschiedliche Inhalte sehen sollte, wenn er die Homepage des Einkaufszentrums betritt.
Das folgende Bild ist ein Beispiel. Der Inhalt auf der Startseite wird zufällig empfohlen, während der Inhalt auf der rechten Seite tatsächlich durch maschinelles Lernen basierend auf den früheren Äußerungen des Benutzers gesendet wird >Gewohnheiten werden berechnet und mit den Elementen in unserem Backend abgeglichen, Inhalte werden basierend auf Benutzerpräferenzen und -verhalten empfohlen.
Jeder Benutzer kommt herein und sieht unterschiedliche Inhalte, sodass das statische Straight-out-Modell nicht funktioniert, da wir nicht die Seiten aller Benutzer einfügen können. Es wird in generiert Es gibt jedoch eine sehr einfache Möglichkeit, dieses Modell zu lösen.
Dynamische DirektausgabeDieses Modell löst die Anforderungen des Produkts, bringt jedoch neue Probleme mit sich. WebView muss Node.js anfordern, um HTML zu erhalten, und Node.js muss Hintergrundseiten zusammenstellen. Die dazwischenliegende Netzwerkzeit und die Hintergrundrechenzeit sind größer als wir es uns vorgestellt haben. Während dieses Vorgangs kann nicht die gesamte Seite gerendert werden. Wenn Benutzer die Homepage unseres Einkaufszentrums betreten, wird ihnen eine leere Seite angezeigt. Der Produktmanager kann dies ebenfalls nicht akzeptieren und Benutzer zahlen nicht dafür.
Außerdem ist es in diesem Modus fast unmöglich, den Cache von WebView selbst zu verwenden, da das CSS/JS im Hintergrund auch vollständig im Backend ausgeführt wird und es für WebView schwierig ist, alles rein zwischenzuspeichern statisches HTML. Um die oben genannten Probleme zu lösen, haben wir einen dynamischen Caching-Mechanismus eingeführt.
Dynamischer CacheFrüher haben wir den gleichen HTML-Code für alle Benutzer im gesamten Netzwerk zwischengespeichert, aber jetzt haben wir dies korrigiert, sodass der für alle Benutzer im gesamten Netzwerk zwischengespeicherte Inhalt Seiten sind, die vom echten Server zurückgezogen wurden.
Wenn der Benutzer die Seite zum zweiten Mal betritt, gibt sonicBridge der Übermittlung der lokal zwischengespeicherten Seite an WebView den Vorrang. Der Benutzer kann den Inhalt sehen, ohne beim Betreten auf die Netzwerkanfrage warten zu müssen Die Verbesserung der Geschwindigkeit ist für den Benutzer zwar relativ groß, bringt jedoch ein weiteres Problem mit sich.
Tatsächlich ist der Inhalt, den Benutzer sehen, jedes Mal anders, wenn sie WebView öffnen. Die von Node.js zurückgegebenen Daten sind daher jedes Mal die neuesten. Daher müssen wir WebView die abgerufenen Daten neu laden lassen, was dem Benutzer angezeigt wird Die Erfahrung ist: Ich habe offensichtlich den lokal zwischengespeicherten HTML-Code geöffnet und den Inhalt gesehen, aber die gesamte Seite wird neu geladen, sobald ich sie betätige. Das Neuladen von WebView ist bei einigen Low-End-Modellen sehr zeitaufwändig. Benutzer können deutlich spüren, dass die gesamte WebView H5-Seite für eine Weile leer bleibt und dann neue Inhalte aktualisiert werden.
In Kombination mit der zuvor erwähnten Erfahrung der statischen direkten Aktualisierung des Teil-DOM können wir den Umfang der Netzwerkübertragung und die an die Seite übermittelte Datenmenge reduzieren. Als Erstes reduzieren wir den Umfang der Netzwerkübertragung und vermeiden eine zu späte Aktualisierung.
Wir haben das Protokoll der Node.js-Gruppe geändert. Wenn sonicBridge zum zweiten Mal Daten anfordert, sendet der Node.js-Server nicht das gesamte HTML wird an sonicBridge zurückgegeben, aber stattdessen wird der Teil zurückgegeben, den wir Daten nennen.
Nachdem wir die Daten erhalten haben, haben wir eine Vereinbarung mit der H5-Seite getroffen, und die native Seite ruft die feste Aktualisierungsfunktion der Seite auf und übergibt die Daten an die Seite. Die Seite aktualisiert teilweise ihren eigenen DOM-Knoten, sodass selbst dann, wenn die Seite aktualisiert werden muss, nicht die gesamte Seite neu geladen wird.
Speziell aus dem Dateninhaltsprozess gibt die erste SonicBridge-Ladeseite immer noch vollständiges HTML zurück, und gleichzeitig wird die ID, die wir template-tag nennen, zurückgegeben -tag markiert den statischen und unveränderten Teil des Hash-Werts auf dieser Seite. Diese Maßnahme dient der Steuerung des Cachings. Wir werden auch einige Tags im zurückgegebenen HTML haben, wie zum Beispiel sonicdiff-banner. Dieses Banner bestimmt seine Aktualisierungs-ID.
Beim zweiten Laden enthalten die zurückgegebenen Daten nicht den gesamten HTML-Code, der zuvor angezeigt wurde, und es werden nur etwa 37 KB an Daten zurückgegeben. Bei diesen Daten handelt es sich tatsächlich um JSON , aber es definiert die DOM-Struktur entsprechend dem vorherigen Beispiel sonicdiff-banner. Um den in H5 ausgeführten Code zu speichern, schreiben wir den DOM-Knotencode direkt in JSON aus, sodass die Seite nur einen ID-Abgleich und eine Aktualisierung durchführen muss.
Es ist schwierig, die 37-KB-Übertragungsdaten zu vermeiden. Wir haben beobachtet, dass die Menge der Aktualisierungsdaten für verschiedene Dienste unterschiedlich ist. Können wir die zur Aktualisierung an die Seite übermittelte Datenmenge reduzieren? Schließlich ändert der Produktmanager nicht jedes Mal viele Daten.
Zusätzlich zu den zuvor erwähnten Maßnahmen werden wir den gesamten HTML-Code und die Vorlage auf der SonicCache-Ebene zwischenspeichern und die Daten auch dorthin extrahieren dataCache erstellen.
Wenn auf die Vorlage zum ersten Mal zugegriffen wird, werden alle variablen Daten entfernt und der verbleibende Seitenrahmen basierend auf den ID-Informationen in sonicdiff entfernt. Wenn der Benutzer es zum zweiten Mal öffnet, muss er nur die zurückgegebenen Daten mit der Vorlage lokal auf dem Client zusammenführen, um den vollständigen HTML-Code zu erhalten.
Nachdem wir jeden Datencache zwischengespeichert haben, machen wir auch einen Unterschied in den Daten. Diesmal gab die Anfrage beispielsweise 37 KB Daten zurück, und die letzten zwischengespeicherten Daten waren ebenfalls 37 KB . der Daten ermitteln wir, wie viel sich tatsächlich intern geändert hat, und geben dann nur die Differenz zur HTML-Aktualisierung an. In den meisten Szenarien muss unsere Seite nur etwa 9 KB an Daten verarbeiten, um die gesamte Seite zu aktualisieren.
Mit dem Cache können Benutzer ihn sehr schnell lokal öffnen. Durch die Übertragung von Differenzdaten wird auch die Zeit für die Aktualisierung und das Warten der Daten verkürzt wird hinzugefügt Das zeitaufwändige Diff reduziert den Seitenaktualisierungsbereich erheblich.
Der gesamte Prozess im Sonic-Modus sieht wie folgt aus: Das Grundprinzip besteht darin, die HTML-Vorlage und die über Bridge angeforderten Daten zwischenzuspeichern.
Möglicherweise haben Sie hier Fragen: Sind die Offline-Server- und Offline-Pre-Push-Strategien, für deren statische Steuerung ich zuvor viel Mühe aufgewendet habe, hier noch nützlich? Tatsächlich verwenden wir immer noch den zuvor erwähnten Offline-Caching-Mechanismus für dynamische Seiten und statische Seiten, da unsere Geschäftsseiten auch über viele öffentliche JS verfügen, z. B. das von QQ bereitgestellte JS API-Paket, und einige werden gemeinsam genutzt Auch CSS wird durch die Offline-Paketstrategie vorab gepusht und wird auch von jedem heruntergeladen, wenn er sich anmeldet.
Nach Abschluss dieses Modus ist der Dateneffekt relativ offensichtlich. Die Leistung des ersten Ladevorgangs und des normalen HTTP-Ladevorgangs ist jedoch nahezu gleich Beim zweiten Öffnen der Seite dauert es normalerweise nur 1 Sekunde, bis die Seite angezeigt wird. In dieser 1 Sekunde ist auch der Aufwand für den Client-Startvorgang und WebView enthalten. Gleichzeitig wird unsere Ladegeschwindigkeit nicht mehr beeinträchtigt Abhängig von der Netzwerkumgebung des Benutzers, unabhängig davon, ob es sich um eine 2G- oder 4G-Ladegeschwindigkeit handelt.
Und es bringt auch einen Vorteil mit sich, wenn das Netzwerk des Benutzers relativ schlecht ist, z. B. wenn es häufig zu Jitters kommt und keine Verbindung möglich ist, da wir über einen lokalen Cache verfügen, kann unsere Seite auch dann geöffnet werden, wenn der Benutzer gerade nicht verbunden ist.
Es wird kein Template-Update-Szenario erwähnt. Das bedeutet, dass sich die von uns extrahierte Vorlage zu diesem Zeitpunkt dynamisch von dem unterscheidet, was wir zuvor erwähnt haben. Befolgen Sie weiterhin den ursprünglichen Prozess des Neuladens von HTML-Seiten. Der Zeitaufwand ist hier relativ hoch, aber unsere Statistiken zeigen, dass die meisten Benutzer immer noch in den Status der Datenaktualisierung fallen, dh in die zweite Öffnung.
Bei der H5-Beschleunigungsoptimierung kann jeder leicht darüber nachdenken, ob wir sollten dauerhafte Verbindungen verwenden. Vermeiden Sie zeitraubende Zugriffe auf die Verbindung, DNS, Handshakes usw. des Servers. Clients wie QQ haben eine dauerhafte Verbindung mit dem Backend-Server. Wenn Sie diese Verbindung verwenden, um eine HTML-Datei vom Backend-Server anzufordern und an WebView zu übergeben, ist das dann schneller, als vorübergehend eine Verbindungsanforderung einzurichten? Wir müssen lediglich einen Reverse-Proxy-Dienst einrichten, um über das QQ-Messaging-Backend auf unseren Node.js-Server zuzugreifen. Dieser Prozess kann gelöst werden, wir gehen jedoch davon aus, dass dieses Modell möglicherweise nicht für alle Szenarien geeignet ist.
Es stimmt, dass einige Apps den dauerhaften Verbindungskanal zum Laden von Seiten verwenden, aber dies ist auf mobilem QQ schwierig, da der dauerhafte Verbindungskanal zwischen dem mobilen QQ-Client und dem Server eine sehr traditionelle CS-Architektur ist . Jedes Mal, wenn ein Anforderungspaket gesendet werden muss, wird nach Erhalt der Antwort mit der nächsten Anforderung fortgefahren.
Dieser Antwortmechanismus bestimmt, dass jedes Mal ein Wartevorgang erforderlich ist, und die Einschränkungen des Socket-Pakets führen dazu, dass die Größe jedes übertragenen Datenpakets begrenzt ist, wie bei unserem 30+ Die KB Die Daten werden wahrscheinlich in fünf oder sechs Datenpakete aufgeteilt. Obwohl die dauerhafte Verbindung verwendet wird, um Verbindungszeit zu sparen, erhöht die mehrfache Hin- und Herkommunikation mit dem Server den Gesamtzeitverbrauch.
Außerdem müssen die vom Node.js-Server zurückgegebenen Daten nicht warten, bis der gesamte HTML-Code geladen ist, bevor er gerendert und angezeigt werden kann erhält das erste Byte in der ÜbertragungDokument Parsing und DOM-Konstruktion.
Wenn wir dauerhafte Verbindungen verwenden möchten, müssen wir wahrscheinlich Schritte wie Verschlüsselung, Entschlüsselung und Paketierung auf der Clientseite durchführen und warten, bis der gesamte HTML-Download abgeschlossen ist Wir glauben, dass dieses Mal die Leistung tatsächlich verlangsamt wird.
Nach der obigen Einführung haben Sie möglicherweise einen groben und intuitiven Eindruck von QQHybrid: 1. Wir sind hier Die Front-End-Entwicklungsstudenten von WebScope haben einen Teil der Arbeit geleistet; 2. Unsere Studenten der nativen Layer-Terminalentwicklung haben das Bridge-Bridging durchgeführt und 3. Unsere Back-End-Studenten haben viele automatische Integrationen und Offline-Server-Push durchgeführt. Die Struktur dieses Teils ist wie folgt:
Als nächstes werde ich den Teil über den Seitenverkehr auf der rechten Seite des Architekturdiagramms vorstellen. Wir haben die Verteilung des Datenverkehrs in jedem Unternehmen gezählt. Wie in der folgenden Abbildung dargestellt, können wir deutlich erkennen, dass der größte Teil des Datenverkehrs für Bildressourcen verbraucht wird. Als wir diese Analyse durchführten, hatten wir jedoch auch Zweifel, ob die Geschäftsmerkmale ermittelt wurden unser Bildkonsum am meisten? Gilt das auch für andere H5-Dienste in QQ Mobile?
Zufällig bot sich uns die Gelegenheit. Während des Frühlingsfestes 2016 veranstaltete Mobile QQ eine Veranstaltung, an der fast alle Unternehmen teilnahmen – Spring Festival Red Sie erinnern sich vielleicht noch daran, wie man während des Frühlingsfestabends 2016 ständig auf den Bildschirm tippte, um rote Umschläge zu erhalten. Diese Art von nationalem Karneval hat zu einem enormen Verkehrsdruck geführt, der jede Sekunde an Benutzer ausgegeben wird, und der Webverkehr, der Benutzer leitet, beträgt etwa Hunderttausende von H5-Seitenöffnungen pro Sekunde 1 TB.
Wir haben den Bildverkehr analysiert und tatsächlich macht er fast die Hälfte aus. Bei einigen von ihnen haben wir Offline-Paket-Pre-Push verwendet, um sie im Voraus an die Mobiltelefone zu senden, aber während der Veranstaltung. Die Bilder im Netzwerk waren Der Datenverkehr beträgt immer noch über 200 GB.
Traffic ist kein Problem, das einfach dadurch gelöst werden kann, dass man dem Betreiber Geld zahlt. Während der Frühlingsfestaktivitäten kam es zu einer Situation, in der der Traffic unter einem einzigen Domainnamen zu diesem Zeitpunkt fast 200 GB betrug , die CDN-Architektur konnte es nicht mehr ertragen.
Wir alle denken, dass hier viel Potenzial liegt, wenn Bildverkehr eingespart werden kann, können Bandbreitenkosten reduziert werden. Der Netzwerkverkehr und der Akkuverbrauch des Mobiltelefons auf Benutzerseite können besser sein, daher hat unser Team neue Dinge zu Bildformaten überprüft.
Jeder kennt WebP und Android hat intern ein Bildformat namens SharpP entwickelt ca. 10 % Einsparung im Vergleich zu WebP. Im Folgenden finden Sie einen Vergleich der Daten, die aus vorhandenen Bildern auf unserem CDN-Server extrahiert wurden.
Die Bildgröße ist dominant, aber wie sieht es mit der Dekodierungsgeschwindigkeit aus? Wir haben für die Analyse High-End-, Midrange- und Low-End-Modelle verwendet. Leider ist SharpP zwar etwas langsamer als WebP oder sogar JPG, aber zum Glück ist die Bildgröße unseres Unternehmens nicht zu groß Dollar mehr auf der Seite sind auch akzeptabel, und wir denken, dass dies vorteilhafter ist, als Zeit beim Warten auf das Netzwerk zu sparen.
Wir planen also, das SharpP-Format im mobilen QQ H5-Geschäft zu fördern, aber die Förderung des neuen Bildformats wird enorme Anwendungskosten mit sich bringen. Erstens sind die meisten Bildlinks fest codiert und die Seite weiß nicht, ob das mobile Endgerät das SharpP-Format dekodieren kann.
Muss die H5-Seite unterschiedliches HTML für verschiedene mobile QQ-Versionen vorbereiten? Oder werden bei der Veröffentlichung von Bildressourcen im CDN zwei Links in unterschiedlichen Formaten generiert und dann basierend auf der Terminalversion in H5 unterschiedliche Links ausgewählt? Diese Entwicklungskosten sind sicherlich inakzeptabel.
Zusätzlich zu Problemen mit dem Bildformat haben wir festgestellt, dass unterschiedliche Benutzermodelle Traffic verschwenden. Unser UI-Design ist normalerweise auf die Bildschirmgröße des iPhone6 zugeschnitten und die Standardeinstellung ist 750 Pixel Bildmaterial. Mobiltelefone mit kleinen Bildschirmen, z. B. 640 Pixel und 480 Pixel, laden auch 750 Pixel-Bilder herunter und verkleinern sie dann beim Rendern.
Dadurch wird tatsächlich viel Bandbreite verschwendet, daher denken wir darüber nach, ob CDN Bilder in verschiedenen Formaten entsprechend der Bildschirmgröße des Mobiltelefons des Benutzers liefern kann.
Diese Bildschirmanpassung-Strategie ist auch mit den Kosten eines nahezu privaten Formats konfrontiert, da das CDN die Situation des nicht kennt Mobiltelefon. Schließlich haben wir die Reshape-Architektur vorgeschlagen, die aus dem vollständigen Link zum Herunterladen von Bildern grob in 4 Ebenen unterteilt werden kann:
Wir rufen an Auf der untersten CDN-Quellseite haben wir ein Bildformat-Konvertierungstool bereitgestellt. Die Geschäftsseite muss sich nicht um die JPG-Produktion kümmern, bevor sie SharpP oder WebP generiert. Sie muss das Bild lediglich auf der CDN-Quellseite veröffentlichen, um es automatisch zu konvertieren ;
Oben sind die CDN-Knoten aufgeführt, auf die die Mobiltelefone der Benutzer zugreifen und die im ganzen Land Server zum Beschleunigen und Zwischenspeichern von Dateien bereitstellen.
Wir haben mit dem Browser-Team zusammengearbeitet, um das SharpP-Dekodierungsformat in den Browserkern zu integrieren, sodass sich das Top-Level-Unternehmen nicht darum kümmern muss, ob der aktuelle Browser WebP oder SharpP unterstützt .
Wenn die Seite geöffnet wird, übermittelt WebView automatisch die Bildschirmgröße des Terminals und die unterstützten Bildformate an den CDN-Knoten. Der CDN-Knoten ruft dann die neuesten Bilder vom Ursprung ab Die Ursprungsseite ist diese. Das entsprechende Bild wurde möglicherweise offline oder in Echtzeit generiert.
Nehmen Sie die WebView-Ebene auseinander. Zusätzlich zur Integration der SharpP-Dekodierungsbibliothek sind andere Dinge relativ einfach, wie zum Beispiel:
Anfordern von Kopf Es werden zusätzliche Felder hinzugefügt, zum Beispiel wird „Pixel/750“ zu „User-Agent“ hinzugefügt. Wenn es sich um eine 480-Pixel-Maschine handelt, wird der Wert zu 480;
SharpP-Protokoll-Header in Accept hinzugefügt: image/sharpP
speichert 3 in der Ursprungsseite *3 Nummer Wenn jedes Geschäftsbild zur Veröffentlichung an die Quellseite gesendet wird, werden 9 Bilder generiert. Der CDN-Knoten fordert entsprechend der Anforderung von WebView den entsprechenden Bildtyp von der CDN-Ursprungsseite an. Für Unternehmen und WebView ist die Anforderung jedoch immer noch derselbe Link, sodass für alle H5-Seiten von Mobile QQ keine Zeile erforderlich ist des Frontends Durch Ändern des Codes können Sie die Größenanpassung und Verkehrseinsparungen genießen, die das Bildformat mit sich bringt.
Das Folgende ist ein anschaulicherer Prozess: Fügen Sie Felder in Akzeptieren hinzu und geben Sie dann das entsprechende Bild zurück:
Diese Technologie ist nicht kompliziert. Ich persönlich glaube nicht, dass es eine tiefe technische Schwelle gibt. Es geht vielmehr darum, die gesamte Kette vom Client über das Web bis zum CDN-Backend zu öffnen. Allerdings stießen wir dabei auch auf einige Fallstricke: Als wir in Graustufen arbeiteten, stellten wir fest, dass sich viele iOS-Nutzer darüber beschwerten, dass Bilder beim Anzeigen der Seite nicht angezeigt werden konnten.
Das hat uns überrascht, da diese Technologie noch nicht auf iOS, sondern nur auf Android eingesetzt wurde. Wir haben den CDN-Code überprüft und es gibt kein Problem. Warum werden SharpP-Bilder an iOS-Benutzer verteilt?
Eine spätere Analyse ergab, dass Betreiber in verschiedenen Regionen Chinas Caching-Dienste anbieten werden, die dem CDN-Cache ähneln. Wenn ein Android-Benutzer zum ersten Mal ein SharpP-Bild anfordert, erhält der Server des Betreibers den SharpP-Format-Link von unserem CDN. Wenn andere iOS-Benutzer in derselben Region während des Cache-Gültigkeitszeitraums Anfragen stellen, stellt der Betreiber fest, dass die URL dieselbe ist, und sendet das Bild direkt im SharpP-Format an den iOS-Benutzer zurück.
Dieses Problem stellt eine Falle in unserer Gesamtarchitektur dar, da wir keine umfassende Überprüfung durchgeführt haben. HTTP verfügt über eine Standardkonvention zur Lösung dieses Caching-Problems. Wenn CDN Inhalte verteilt, müssen Sie sich bei der Angabe des Caches über das Vary-Feld auf die Felder in Accept und User-Agent beziehen. Nachdem wir dieses Vary hinzugefügt haben, ist das Problem im Grunde gelöst.
Dieser Fall hat uns zusätzliche Inspiration gegeben. In unserem aktuellen Netzwerk hat das Pixelfeld drei Werte: 480px, 640px und 750px. Wir haben intern darüber diskutiert, ob wir die Bildschirmgröße direkt in den User-Agent schreiben können, damit wir, wenn Android mit einigen neuen Bildschirmauflösungen herauskommt, auch im Hintergrund eine bessere Anpassung vornehmen und für jedes Bild unterschiedliche Formate generieren können.
Wenn wir dies tun, wird es einen enormen Back-to-Origin-Overhead für den Betreiber und unseren eigenen CDN-Cache mit sich bringen. Jedes Bild mit einer Auflösung muss zwischengespeichert werden, z. B. 498 Pixel. Wenn der Zwischenbetreiber nicht über den Cache für dieses Modell verfügt, wird er an unseren Dienst gesendet, um zur Quelle zurückzukehren. Auf diese Weise bringen N-Bildschirmgrößen die Rückkehr zu Unser CDN-Quellendruck.
Um auf das Thema zurückzukommen: Der endgültige Dateneffekt ist ebenfalls ziemlich offensichtlich. Das Bild unten zeigt unsere Effektdaten in Android-Graustufen. Der Bildverkehr unseres H5-Unternehmens sank von 40+ GB auf 20+ GB. Für Tencent sind 20+ GB Bandbreite keine besonders hohen Kosten, aber im Szenario einer Frühlingsfestveranstaltung kann die Geschäftsfläche fast verdoppelt werden. Ein zusätzlicher Vorteil besteht darin, dass die Zeit, die Benutzer auf das Anzeigen von Seitenbildern warten, relativ verkürzt wird und der benutzerseitige Datenverkehr ebenfalls um die Hälfte eingespart wird.
Als wir das Problem der Seitenladegeschwindigkeit und des Verkehrsverbrauchs gelöst hatten, begannen wir auch damit Betrachten Sie es als Stabilitätsprobleme von H5 bei schnellem Betrieb. Ich glaube, dass Front-End-Entwickler schon einmal Situationen erlebt haben, in denen andere Funktionen nicht mehr richtig funktionieren, sobald der Code einer bestimmten Seite geändert wird. Bei Verwendung der Hybridentwicklung ist es sehr wahrscheinlich, dass native viele APIs für JS-Seiten bereitstellt. Kleine Änderungen auf der Clientseite können dazu führen, dass die JS-API beeinträchtigt wird und die H5-Seiten im gesamten Netzwerk nicht ordnungsgemäß funktionieren.
Neben der Funktionsstabilität gibt es noch ein weiteres großes Problem. Wir veröffentlichen täglich Frontend-Seiten. Wie kann also die Optimierungsleistung der Seite nicht beeinträchtigt werden? Wir haben endlich Zeit damit verbracht, die Seitenladeleistung auf 1 Sekunde zu reduzieren. Wird es einige Frontend-Änderungen geben, wie z. B. die Einführung weiterer JS/CSS-Abhängigkeiten für externe Links, die die Leistung der gesamten Seite beeinträchtigen? Wir haben einige Tools entwickelt, um diese Probleme zu lösen.
Das nennen wir intern Quick Automation. Wir werden alle Testfallsätze im Frontend als automatisierte Tests schreiben und dann jeden Tag alle Testfallsätze auf allen Seiten im gesamten Netzwerk ausführen, um zu überprüfen, ob die Funktionen normal sind.
Wir überwachen die Leistung des Webs mit dem Web-Performance-Test. Das erste, was wir hier beobachten, ist jedes Mal, wenn die Seite aufgerufen wird Der Datenverkehr wird verbraucht, daher werden wir Tools verwenden, um alle geladenen Bilder auf der Seite zu analysieren, um zu sehen, ob einige davon in SharpP konvertiert werden können, aber immer noch JPG verwenden. Mit diesem Überwachungssatz können H5-Entwickler außerhalb unseres Teams aufgefordert werden, ihre Seiten zu optimieren.
Das Front-End erwähnt oft die Notwendigkeit, die Anzahl der Anfragen während der Optimierung usw. zu reduzieren. Dies kann als militärische Regel betrachtet werden und wir werden sie während des Tests überwachen. Wir haben einige Methoden der clientseitigen Optimierung bisher nicht im Detail erwähnt, aber wir haben auch die Zeit überwacht, die zum Starten von WebView auf dem Client benötigt wird.
Wir haben auch einen strengeren Front-End-Release-Prozess, der alle im geschrieben und getestet wurde Testumgebung Bestandener Code muss die QTA- und WPT-Verifizierung bestehen, wenn er für die formale Umgebung freigegeben werden soll. Wenn die Erfolgsquote des automatisierten Tests weniger als 95 % beträgt, darf er nicht freigegeben werden.
Nach der Veröffentlichung in der offiziellen Umgebung verfügen wir auch über ein umfassendes Score-Überwachungssystem im externen Netzwerk. Der primäre Überwachungsindikator ist die Geschwindigkeit. Wir unterteilen die Seitenöffnungsgeschwindigkeit in Client-Zeitverbrauch und Netzwerk-Zeitverbrauch. und Seitenzeitverbrauch ermitteln und separat überwachen.
Wir werden jeden Tag den folgenden Überwachungsbericht ausgeben, um die täglichen Geschwindigkeitsänderungen zu beobachten. Hier geht es uns nicht nur um die Leistung von Im gesamten Netzwerk machen wir uns mehr Sorgen um die Erfahrung langsamer Benutzer, beispielsweise um den aktuellen Anteil von Benutzern mit mehr als 5 Sekunden.
Darüber hinaus stößt H5 häufig auf bestimmte JS-Fehler, die dazu führen, dass die Seite abnormal ist, das Laden langsam ist und der Benutzer zu lange einen weißen Bildschirm sieht usw. Wir überwachen diese systematisch.
Zusätzlich zu dem zuvor Erwähnten haben wir auch eine Debug-Plattform erstellt, viele Debugging Die Funktion wurde vorab in allen mobilen QQ-Terminals implementiert. Wir können Remote-Befehle verwenden, um die DNS-Auflösung des Benutzers zu überprüfen, welcher Server angegriffen wurde, ob der Benutzer vom Betreiber gekapert wurde usw.
Neben der Leistungsoptimierung wird auch das CDN optimiert Die Struktur wurde angepasst und operative Überwachungsinstrumente entwickelt. Ich denke, es ist das Betriebsüberwachungssystem, das es unseren gesamten H5- und Hybird-Teams ermöglicht, Seiten mutig zu ändern und neue Funktionen zu veröffentlichen und gleichzeitig Stabilität und Zuverlässigkeit zu gewährleisten.
Der gesamte Prozess hat uns auch das Gefühl gegeben, dass die Hybridarchitektur nicht so ist, wie es alle zuvor verstanden haben. Sie funktioniert einfach gut, wenn der Client und das Frontend im Großen und Ganzen zusammenarbeiten Architektursystem, die Backend-Technologie spielt auch eine große Rolle. Wir haben auch um die Unterstützung des Betriebs- und Wartungsteams für die CDN-Transformation gebeten, und das Test- und Entwicklungsteam hat auch an QTA und WPT teilgenommen. Man kann sagen, dass die Etablierung des gesamten Systems das Ergebnis der Zusammenarbeit aller Positionen ist.
Empfohlene verwandte Artikel:
Web-Front-End-Lernroute: Schnelle Einführung in die WEB-Front-End-Entwicklung