Unter der Haube Turbo-Seiten: Architektur der Webseite Fast Download-Technologie

Hallo, ich heiße Stas Makeev. Bei Yandex leite ich die Entwicklung von Technologien für Turbo-Seiten, die auch bei langsamer Verbindung ein schnelles Laden von Inhalten ermöglichen. Heute werde ich den Lesern von Habr ein wenig über die Architektur unseres Projekts erzählen.

Das Glück des Benutzers wird maßgeblich davon beeinflusst, wie schnell er den Inhalt der Webseite sieht. Geschwindigkeit macht vielen Sorgen: Im mobilen App Store verfügt nur Speedtest über mehr als hundert Millionen Installationen. Anbieter, Mobilfunkbetreiber, Website- und Anwendungsentwickler bemühen sich um den schnellsten Zugriff auf Inhalte, damit die Kunden zufrieden sind.

Die durchschnittliche Download-Geschwindigkeit in russischen Mobilfunknetzen beträgt 16,26 Mbit / s - dies ist ein ziemlich guter Indikator. Die Verbindungsgeschwindigkeit ist jedoch ungleichmäßig. Wir sind immer noch mit einer langsamen Internetverbindung konfrontiert - 3G, 2G, EDGE. Sicherlich befanden Sie sich in einer Situation, in der in einem Café oder Einkaufszentrum, auf der Straße oder in einem Landhaus die übliche hohe Geschwindigkeit stark reduziert wird: Die Standorte werden für mehrere zehn Sekunden oder sogar länger geladen.

Die Turbo-Page-Technologie löst das Problem des Zugriffs auf Inhalte, auch bei niedrigen oder instabilen Verbindungsgeschwindigkeiten. Dies ist wichtig für Websitebesitzer, bei denen ein geringerer Prozentsatz der Besucher während des Übergangs von der Suche "abfällt".



Wie Turbo-Seiten funktionieren


Der Websitebesitzer registriert den RSS-Feed in Yandex.Webmaster. Der Feed wird in das Turbo Pages-Inhaltssystem eingegeben, das alle paar Minuten aktualisiert wird. Schwere Inhalte - hauptsächlich Bilder und Videos - werden zwischengespeichert und in einem CDN angeordnet. Zusätzlich zu RSS können Inhalte über die API und den Autoparser übertragen werden.
Das Volumen der zwischengespeicherten Bilder von Turbo-Seiten nähert sich 100 TB

Die Zuverlässigkeit und Fehlertoleranz des Systems ist uns wichtig, daher erstellen wir mehrere Replikate der Daten und speichern sie in unseren drei Rechenzentren. In jedem Rechenzentrum verarbeiten Hunderte von Servern Tausende von Anforderungen pro Sekunde, sodass Sie die Last flexibel ausgleichen können.

Das Turbo Pages-Inhaltssystem verdient einen separaten Beitrag, und wir werden ihn schreiben. Im Moment beschränken wir uns auf ein vereinfachtes Schema.



Was passiert, wenn Sie eine URL in einem Browser öffnen?


Wenn der Benutzer die Turbo-Seite aufruft, geschieht Folgendes unter der Haube:



Der HTTP-Adapter verarbeitet die HTTP-Anforderung des Benutzers und sendet eine Anforderung an das gewünschte Diagramm in AppHost und Report-Renderer.

AppHost ist eine spezielle Komponente, die die Netzwerkinteraktion von Quellen kapselt und als Abhängigkeitsdiagramm bezeichnet wird. Quellen werden in der Reihenfolge der topologischen Sortierung in diesem Diagramm abgefragt, wobei die gesamte Geschäftslogik in sie und in die Diagrammkonfiguration eingenäht ist. Insbesondere auf Diagrammebene wird der KV-Speicher abgefragt und eine Datenanforderung an APIs von Drittanbietern gesendet.

Report-Renderer ist eine in node.js geschriebene Anwendung, die JSON-Eingaben akzeptiert, in JS geschriebene Vorlagen ausführt und eine Zeichenfolge zurückgibt.

All dies geschieht fast sofort.

Was beeinflusst die Download-Geschwindigkeit?


Wir arbeiten an allen Aspekten der Geschwindigkeit: von der Implementierung von HTTP / 2 auf dem Balancer über die Optimierung des TLS-Handshakes bis zur manuellen Optimierung von SVG. In diesem Fall müssen Sie verstehen, woraus sich die Endbenutzergeschwindigkeit zusammensetzt.

Innerhalb des Teams unterscheiden wir drei Stufen der Anforderungsverarbeitung: Server, Netzwerk und Client.

Server

Dies umfasst alles, was in den Rechenzentren geschieht: vom Eingang der HTTP-Anforderung auf unserem Server bis zur Generierung der HTML-Seite, die direkt an den Client gesendet wird.

Die Bearbeitungszeit für Anforderungen auf dem Server sollte minimal sein. Trotz der relativ kleinen Werte sind absolut alle Benutzeranfragen betroffen. Darüber hinaus finden alle Prozesse in unserer kontrollierten Umgebung statt - es kann einfach keine Entschuldigung für große Verzögerungen geben.

Die Serverzeit besteht aus Netzwerkinteraktionen zwischen den Scheitelpunkten des Quellabhängigkeitsgraphen und den Betriebszeiten der einzelnen Scheitelpunkte. Wir werden uns jedoch nicht auf die Funktionen der Netzwerkinfrastruktur von Yandex-Rechenzentren konzentrieren - sie verdienen einen separaten Beitrag.

Ich möchte der zweiten Komponente mehr Aufmerksamkeit schenken - der Ausführungszeit jedes der Peaks. Schauen wir uns als Beispiel unsere Prinzipien und Tools für die Arbeit mit der Report-Renderer-Komponente an, die für die Generierung von HTML verantwortlich ist. Für andere Komponenten sind sie sehr ähnlich.

In unserem CI-Prozess gibt es Aufgaben, die Pull-Anforderungen in dev akzeptieren und grundlegende Überprüfungen für jedes Commit für den Feature-Zweig durchführen. Wenn Indikatoren die angegebenen Grenzwerte überschreiten, wird der Einfluss in dev eingefroren, bis die Gründe geklärt sind.

Wichtige Kennzahlen in dieser Phase:

  • Vorlagenzeit;
  • zusammenfassende Seitengröße;
  • Größe der statischen Dateien.

Abhängig von den Daten erfassen wir für jede Seite Client-Statiken (CSS und JS). Die Bundles mit Blöcken selbst sind jedoch unabhängig von der Anforderung. Daher reicht es aus, die Größe der Dateien in der Verzweigung mit ähnlichen Dateien in dev zu vergleichen. Für verschiedene Dateitypen haben wir unterschiedliche Schwellenwerte festgelegt. Danach kann die Aufgabe nicht mehr ohne "OK" von den für die Geschwindigkeit Verantwortlichen in dev übernommen werden.

In der Regel erfolgt eine gemeinsame Analyse des Codes und es wird nach Optimierungsmöglichkeiten gesucht.

Wir müssen bei Seitengrößenmetriken und Vorlagenzeit anders vorgehen, da diese stark von einer bestimmten Anforderung abhängen und eine gewisse statistische Sicherheit erforderlich ist. Darüber hinaus können Sie keine synthetischen Abfragen durchführen, da dies unehrliche Messungen sind. Daher sammeln wir ständig zufällige Benutzeranforderungen für Zugriffsprotokolle, bilden daraus "Kassetten" und "schießen" sie mit Mustern in der Verzweigung mit Änderungen und mit dev. Auf diese Weise können Sie Änderungen auch bei nicht sehr beliebten Anfragen abfangen.

Wir haben mehrere "Anforderungskörbe", mit denen wir den größten Teil des Datenverkehrs zu Turbo-Seiten abdecken können.

Neben der Optimierung unserer Vorlagen folgen wir den Optimierungen in V8. Die Umstellung auf TurboFan führte beispielsweise zu hervorragenden Ergebnissen: Die serverseitige Vorlagenzeit wurde erheblich verkürzt.


Die Vorlagenzeit für Server wurde nach dem Wechsel zu TurboFan verkürzt

Netzwerk

Im Netzwerkteil enthalten wir alles, was zwischen Client und Server geschieht: Datenübertragungszeit, Seitengröße und Statik sowie Ressourcen-Caching. Das ist schon interessanter, denn von unseren gemütlichen Rechenzentren aus befinden wir uns in der wilden Außenwelt, in der nicht alles von uns abhängt. Messungen werden etwas komplizierter und vor allem - Sie können in Hunderten von Millisekunden wirklich greifbare Ergebnisse erzielen.

Hier ist was wir tun.

Wir haben die TCP- und TLS-Parameter verdreht, sodass Sie mehrere RTT (Round Trip Time) gewinnen können. Dies führt zu hervorragenden Ergebnissen in Netzwerken mit hoher Latenz. Unsere Kollegen haben bereits darüber geschrieben , deshalb werde ich nicht weiter darauf eingehen.

Die Größe der übertragenen Daten kann die Download-Geschwindigkeit stark beeinflussen. Daher versuchen wir, nur das zu senden, was die aktuelle Seite am effizientesten benötigt.

Bilder in unseren Oberflächen werden mit ImageOptim optimiert. Um SVG zu optimieren, verwenden wir nicht nur SVGO , sondern sind auch nicht zu faul, um den Inhalt zu untersuchen und ihn nach Möglichkeit von Hand zu optimieren.

Wir laden Bilder von Websitebesitzern auf ein spezielles CDN hoch, das für das Rendern von Bildern optimiert ist. Wir beschneiden das Exif- und Farbprofil des Bildes, indem wir es zuerst in sRGB konvertieren. Die Bitrate wird auf 8 Bit pro Kanal reduziert, der Komprimierungspegel auf 85 eingestellt. Der Lanczos-Filter wird zum Ändern der Größe verwendet.

Wir erstellen Dutzende von Optionen für jedes Bild für eine Kombination verschiedener Bildschirmgrößen unter Berücksichtigung der Pixeldichte (Retina-Displays). Und natürlich codieren wir Bilder automatisch im WebP-Format, sofern dies vom Browser unterstützt wird.
Textformate (HTML, JavaScript, CSS) werden mit gzip / zopfli und brotli komprimiert, sofern der Browser dies unterstützt.

Es ist wichtig, die Entfernung von Benutzern von Servern nicht zu vergessen. Turbo-Seiten werden in vielen Regionen verwendet, und der Inhalt kann beliebig sein. Wir gehen also keine Kompromisse ein und reduzieren die Latenz auch in den entlegensten Regionen, in denen wir CDN verwenden, das ständig erweitert wird.

Und die schnellste Abfrage ist natürlich, dass sie das überhaupt nicht tun. Alle Statiken werden mit ewigem Caching von einer separaten Domain ohne Cookies angegeben. Um den Cache-Treffer zu erhöhen, kann sie auf der Hauptseite und der Seite mit den Suchergebnissen zusätzlich aufgewärmt werden.

Kunde

Es reicht nicht aus, eine Serverantwort zu erstellen und diese über das Netzwerk an den Browser zu senden. Sie muss dennoch effektiv angezeigt werden. Wir optimieren die Startzeit für das Rendern der Seite, damit die Person den Inhalt schneller lesen kann.

Im HTML-Header „erwärmen“ wir die Verbindung zu unseren statischen Verteilungsservern und laden sie zusätzlich vor. Stile werden in die Seite eingefügt, sodass der Browser mit dem Rendern der Seite beginnen kann, ohne darauf zu warten, dass die Stile über das Netzwerk geladen werden.

Inhaltsbilder, Einbettungen und Anzeigen werden nicht sofort geladen, sondern beim Lesen der Seite, wenn sie sich dem Sichtfeld des Benutzers nähern.

JavaScript ist teilweise in HTML eingebettet, und alle anderen Skripte werden am Ende mit separaten HTTP-Anforderungen geladen. Für den Einstieg wichtige Skripte, Fehler- und Metrikerfassung sowie Komponenten, die nicht häufig auf der Seite gefunden werden, sind in die Seite eingebettet.

Wir erfassen Metriken zum Laden von RUM-Seiten. Das kritischste: die Zeit bis zum ersten Byte, der ersten Zeichnung und dem Einsetzen der Interaktivität, wenn alle Skripte die Initialisierung abgeschlossen haben und der Benutzer die Seite verwenden kann.

Die meisten Benutzer greifen nicht direkt auf Turbo-Seiten zu, sondern über andere Yandex-Dienste. Wir wollten die Ladezeit der Seite im Kontext der Benutzererfahrung bewerten. Nicht nur abstrakte Zeit im luftleeren Raum, sondern eine Metrik dafür, wie der Benutzer alles sieht.

Also formulierten wir die integrale Geschwindigkeitsmetrik:
max (firstContentfulPaint, firstImageLoadTime, timeToVisible) — timeToClick

Wo:

  • timeToClick - absolute Klickzeit, die zur Anzeige der Turbo-Seite führte. Dies kann ein Klick auf ein Snippet auf der Suchergebnisseite oder auf eine Karte in Yandex.Zen sein.
  • firstImageLoadTime - absolute Ladezeit des ersten Inhaltsbilds auf dem ersten Bildschirm.
  • timeToVisible - Die absolute Zeit, zu der die Seite sichtbar wird. Dies gilt für Fälle, in denen die Seite im Hintergrund geladen wurde.

Und habe eine User Experience-Metrik:

  • Wenn 2/3 des Bildschirms von einem Bild belegt sind, das noch nicht geladen wurde, ist die Integrität der Metrik firstContentfulPaint eher zweifelhaft.
  • Es gibt viele Event-Handler auf den Links, zwischen dem Klicken und der tatsächlichen Startzeit der Seite, die geladen werden kann, kann eine Zeit ungleich Null vergehen, was ich gerne verstehen würde.



Wir entwickeln ständig Technologien weiter, damit Websites mehr Besucher anziehen. Jetzt wird eine Turbo-Seite im Durchschnitt 15-mal schneller geladen als eine normale mobile Version. Zehntausende von Websites verwenden Turbo, und die Gesamtzahl der Besuche beträgt mehr als 12 Milliarden.

All dies ist das Ergebnis der Arbeit von Entwicklern, Support-Services, Managern, die mit Website-Eigentümern zusammenarbeiten, und vielen anderen. Mit der Zeit erweitert sich das Team natürlich. Zum Beispiel suchen wir jetzt Frontend- und Backend-Spezialisten und freuen uns über neue Kollegen.

Welche Komponenten der Turbo Page-Technologie möchten Sie in Zukunft detailliertere technische Materialien lesen? Welche Erfahrung würde Sie interessieren? Wir freuen uns auch über Feedback und Ideen. Vielen Dank!

Source: https://habr.com/ru/post/de460373/


All Articles