Wenn eine Webseite eine einzelne CSS-Datei und ein Bild enthält, warum verschwenden Browser und Server Zeit mit dieser herkömmlichen zeitaufwendigen Route:
- Der Browser sendet eine erste GET-Anforderung für die Webseite und wartet auf die Antwort des Servers.
- Der Browser sendet eine weitere GET-Anforderung für die CSS-Datei und wartet auf die Antwort des Servers.
- Der Browser sendet eine weitere GET-Anforderung für die Image-Datei und wartet auf die Antwort des Servers.
Wann könnten sie stattdessen diese kurze, direkte und zeitsparende Route nutzen?
- Der Browser sendet eine GET-Anfrage für eine Webseite.
- Der Webserver antwortet mit ( index.html gefolgt von style.css und image.jpg )
performance
webserver
http
resources
Ahmed
quelle
quelle
Antworten:
Die kurze Antwort lautet "Weil HTTP nicht dafür entwickelt wurde".
Tim Berners-Lee hat kein effizientes und erweiterbares Netzwerkprotokoll entworfen. Sein einziges Designziel war die Einfachheit. (Der Professor meiner Networking-Klasse am College sagte, er hätte den Beruf den Fachleuten überlassen sollen.) Das Problem, das Sie darlegen, ist nur eines der vielen Probleme mit dem HTTP-Protokoll. In seiner ursprünglichen Form:
Das Protokoll wurde später überarbeitet, um viele dieser Probleme zu lösen:
GET /foo.html HTTP/1.1
Connection: keep-alive
Zu diesem Zeitpunkt wurde HTTP so weit wie möglich entfernt, ohne die Abwärtskompatibilität zu beeinträchtigen.
Sie sind nicht die erste Person, die vorschlägt, dass eine Seite und alle zugehörigen Ressourcen an den Client gesendet werden sollen. Tatsächlich hat Google ein Protokoll namens SPDY entwickelt .
Heute können sowohl Chrome als auch Firefox SPDY anstelle von HTTP für Server verwenden, die dies unterstützen. Auf der SPDY-Website stehen im Vergleich zu HTTP folgende Hauptmerkmale zur Verfügung:
Wenn Sie Ihre Website mit SPDY für Browser bereitstellen möchten, die dies unterstützen, können Sie dies tun. Zum Beispiel hat Apache mod_spdy .
SPDY ist die Basis für HTTP Version 2 mit Server-Push-Technologie geworden.
quelle
Ihr Webbrowser kennt die zusätzlichen Ressourcen erst, wenn er die Webseite (HTML) vom Server herunterlädt, die die Links zu diesen Ressourcen enthält.
Sie fragen sich vielleicht, warum der Server bei der ersten Anforderung der Webseite nicht einfach sein eigenes HTML analysiert und alle zusätzlichen Ressourcen an den Webbrowser sendet. Dies liegt daran, dass die Ressourcen möglicherweise auf mehrere Server verteilt sind und der Webbrowser möglicherweise nicht alle Ressourcen benötigt, da bereits einige zwischengespeichert sind oder diese möglicherweise nicht unterstützt werden.
Der Webbrowser verwaltet einen Cache mit Ressourcen, sodass nicht immer wieder dieselben Ressourcen von den Servern heruntergeladen werden müssen, auf denen sie gehostet werden. Wenn Sie auf verschiedenen Seiten einer Website navigieren, die alle dieselbe jQuery-Bibliothek verwenden, möchten Sie diese Bibliothek nicht jedes Mal herunterladen, sondern nur beim ersten Mal.
Wenn der Webbrowser eine Webseite vom Server abruft, prüft er, welche verknüpften Ressourcen sich noch NICHT im Cache befinden, und stellt dann zusätzliche HTTP-Anforderungen für diese Ressourcen. Ziemlich einfach, sehr flexibel und erweiterbar.
Ein Webbrowser kann normalerweise zwei HTTP-Anfragen gleichzeitig stellen. Dies ist nicht anders als bei AJAX - beide sind asynchrone Methoden zum Laden von Webseiten - asynchrones Laden von Dateien und asynchrones Laden von Inhalten. Mit Keep-Alive können wir über eine Verbindung mehrere Anfragen stellen, und mit Pipelining können wir mehrere Anfragen stellen, ohne auf Antworten warten zu müssen. Beide Techniken sind sehr schnell, da der größte Overhead normalerweise durch das Öffnen / Schließen von TCP-Verbindungen entsteht:
Ein bisschen Webprotokoll ...
Die Webseiten begannen als reine Text-E-Mail, und Computersysteme entwickelten sich aus dieser Idee heraus und bildeten eine etwas freie Kommunikationsplattform. Die Webserver waren zu diesem Zeitpunkt noch proprietär. Später wurden der "E-Mail-Spezifikation" weitere Ebenen in Form von zusätzlichen MIME-Typen wie Bildern, Stilen, Skripten usw. hinzugefügt. Immerhin steht MIME für Multi-Purpose Internet Mail Extension. Früher oder später hatten wir eine im Wesentlichen multimediale E-Mail-Kommunikation, standardisierte Webserver und Webseiten.
Mit der Weiterentwicklung dieser Technologie müssen Entwickler in die Lage versetzt werden, schrittweise neue Funktionen zu integrieren, ohne vorhandene Software zu beschädigen. Wenn beispielsweise der Spezifikation ein neuer MIME-Typ hinzugefügt wird - sagen wir JPEG -, dauert es einige Zeit, bis Webserver und Webbrowser dies implementieren. Sie zwingen JPEG nicht plötzlich in die Spezifikation und beginnen, es an alle Webbrowser zu senden. Sie ermöglichen dem Webbrowser, die unterstützten Ressourcen anzufordern, wodurch alle zufrieden sind und die Technologie voranschreitet. Benötigt ein Bildschirmleser alle JPEGs auf einer Webseite? Wahrscheinlich nicht. Sollten Sie gezwungen sein, eine Reihe von Javascript-Dateien herunterzuladen, wenn Ihr Gerät kein Javascript unterstützt? Wahrscheinlich nicht. Muss der Googlebot alle Ihre Javascript-Dateien herunterladen, um Ihre Website ordnungsgemäß zu indizieren? Nee.
Quelle: Ich habe einen ereignisbasierten Webserver wie Node.js entwickelt. Es heißt Rapid Server .
Verweise:
Weitere Lektüre:
quelle
https://
Senden großer öffentlich verteilter Dateien, die authentifiziert, aber nicht vertraulich behandelt werden müssen: Fügen Sie in die URL einen Hash bestimmter Teile des Headers einer legitimen Antwort ein, was wiederum der Fall sein könnte Enthalten Sie entweder eine Signatur oder einen Hash der Datennutzdaten, und lassen Sie die empfangenen Daten vom Browser anhand des Headers validieren? Ein solches Design würde nicht nur einige SSL-Handshake-Schritte einsparen, sondern vor allem das Zwischenspeichern von Proxys ermöglichen. Rufen Sie die URL über einen SSL-Link ab, und die Daten können von überall eingespeist werden.Weil sie nicht wissen, was diese Ressourcen sind. Die Assets, die für eine Webseite erforderlich sind, sind im HTML-Code enthalten. Erst wenn ein Parser feststellt, um welche Assets es sich handelt, kann er vom Benutzeragenten angefordert werden.
Sobald diese Assets bekannt sind, müssen sie einzeln bereitgestellt werden, damit die richtigen Header (dh der Inhaltstyp) bereitgestellt werden können, damit der Benutzeragent weiß, wie er damit umgeht.
quelle
<head>
Element analysiert, das nach alternativen RSS-Links sucht, um genau das zu finden. Der Client kann eine Liste von senden was es interessiert, aber dann muss es wissen, was verfügbar ist und wir sind wieder am AnfangDenn in Ihrem Beispiel würde der Webserver immer CSS und Bilder senden, unabhängig davon, ob der Client bereits über diese verfügt. Dadurch würde Bandbreite stark verschwendet (und die Verbindung wird langsamer anstatt schneller, da die Latenz verringert wird, was vermutlich Ihre Absicht war). Beachten Sie, dass CSS-, JavaScript- und Bilddateien in der Regel aus genau diesem Grund mit sehr langen Ablaufzeiten gesendet werden (wenn Sie sie ändern müssen, ändern Sie einfach den Dateinamen, um eine neue Kopie zu erzwingen, die erneut für lange Zeit zwischengespeichert wird).
Jetzt können Sie versuchen, diese Bandbreitenverschwendung zu umgehen, indem Sie " OK " sagen. Der Client kann jedoch angeben, dass einige dieser Ressourcen bereits vorhanden sind, sodass der Server sie nicht erneut sendet. " So etwas wie:
Und dann werden nur die Dateien, die sich nicht geändert haben, über eine TCP-Verbindung gesendet (mithilfe von HTTP-Pipelining über eine dauerhafte Verbindung). Und rate was? So funktioniert es bereits (Sie können auch If-Modified-Since anstelle von If-None-Match verwenden ).
Wenn Sie jedoch die Latenz reduzieren möchten, indem Sie viel Bandbreite verschwenden (wie in Ihrer ursprünglichen Anfrage), können Sie dies heute mit Standard-HTTP / 1.1 bei der Gestaltung Ihrer Website tun. Der Grund, warum die meisten Leute es nicht tun, ist, dass sie es nicht für wert halten.
Um dies zu tun, müssen Sie kein CSS oder JavaScript in einer separaten Datei haben. Sie können diese in die Haupt-HTML-Datei einbinden, indem Sie
<style>
und<script>
-Tags verwenden (Sie müssen es wahrscheinlich nicht einmal manuell tun, Ihre Template-Engine kann es wahrscheinlich automatisch tun). . Sie können sogar Bilder in die HTML-Datei einbinden , indem Sie den Daten-URI wie folgt verwenden:Natürlich erhöht die Base64-Codierung die Bandbreitennutzung geringfügig, aber wenn Sie sich nicht für verschwendete Bandbreite interessieren, sollte dies kein Problem sein.
Wenn es Sie wirklich interessiert, können Sie Ihre Web-Skripte sogar so intelligent gestalten, dass Sie das Beste aus beiden Welten herausholen: Senden Sie auf erste Anfrage (Benutzer hat kein Cookie) alles (CSS, JavaScript, Bilder), das in einem einzigen HTML-Code eingebettet ist Datei wie oben beschrieben, fügen Sie einen Link rel = "Prefetch" -Tags für externe Kopien der Dateien hinzu und fügen Sie ein Cookie hinzu. Hat der Benutzer bereits ein Cookie (zB das er schon einmal besucht hat), dann schicke ihm einfach ein normales HTML mit
<img src="example.jpg">
,<link rel="stylesheet" type="text/css" href="style.css">
etc.Beim ersten Besuch des Browsers wird also nur eine einzige HTML-Datei angefordert und alles abgerufen und angezeigt. Dann würde es (im Leerlauf) angegebenes externes CSS, JS, Images vorladen. Beim nächsten Besuch des Benutzers würde der Browser nur geänderte Ressourcen anfordern und abrufen (wahrscheinlich nur neues HTML).
Die zusätzlichen CSS + JS + -Bilddaten werden immer nur zweimal gesendet, selbst wenn Sie hunderte Male auf der Website geklickt haben. Viel besser als hunderte Male, wie von Ihrer vorgeschlagenen Lösung vorgeschlagen. Und es würde niemals (weder beim ersten noch beim nächsten Mal) mehr als eine latenzerhöhende Hin- und Rückfahrt verwenden.
Wenn das nach zu viel Arbeit klingt und Sie nicht mit einem anderen Protokoll wie SPDY arbeiten möchten , gibt es bereits Module wie mod_pagespeed für Apache, die einen Teil dieser Arbeit automatisch für Sie erledigen können (Zusammenführen mehrerer CSS / JS-Dateien) Sie können kleine CSS-Dateien automatisch in eine Zeile einfügen und diese verkleinern, kleine Bilder mit Platzhaltern in die Zeile einfügen, während Sie darauf warten, dass Originale geladen werden, Bilder verzögert geladen werden usw.), ohne dass Sie eine einzelne Zeile Ihrer Webseite ändern müssen.
quelle
HTTP2 basiert auf SPDY und macht genau das, was Sie vorschlagen:
Weitere Informationen finden Sie unter HTTP 2 - Häufig gestellte Fragen
quelle
Weil es nicht voraussetzt, dass diese Dinge tatsächlich benötigt werden .
Das Protokoll definiert keine spezielle Behandlung für einen bestimmten Dateityp oder Benutzeragenten. Der Unterschied zwischen beispielsweise einer HTML-Datei und einem PNG-Bild ist nicht bekannt. Um zu tun, was Sie verlangen, müsste der Webserver den Dateityp identifizieren, ihn analysieren, um herauszufinden, auf welche anderen Dateien er verweist, und dann bestimmen, welche anderen Dateien tatsächlich benötigt werden, je nachdem, was Sie vorhaben die Datei . Hier gibt es drei große Probleme.
Das erste Problem besteht darin, dass es keine standardmäßige, zuverlässige Methode zum Identifizieren von Dateitypen auf der Serverseite gibt . HTTP verwaltet sich über den Content-Type-Mechanismus, aber das hilft dem Server nicht, der dies selbst herausfinden muss (teilweise damit er weiß, was er in den Content-Type einfügt). Dateinamenerweiterungen werden weitgehend unterstützt, sind jedoch zerbrechlich und leicht zu täuschen, manchmal aus böswilligen Gründen. Dateisystem-Metadaten sind weniger anfällig, aber die meisten Systeme unterstützen sie nicht sehr gut, sodass sich die Server nicht einmal darum kümmern. Content-Sniffing (wie es einige Browser und der Unix-
file
Befehl versuchen) kann robust sein, wenn Sie bereit sind, es teuer zu machen, aber robustes Sniffing ist zu teuer, um auf der Serverseite praktikabel zu sein, und billiges Sniffing ist nicht robust genug.Das zweite Problem ist, dass das Parsen einer Datei rechnerisch teuer ist . Dies ist insofern etwas mit dem ersten verknüpft, als Sie die Datei auf verschiedene Arten analysieren müssten, wenn Sie den Inhalt zuverlässig durchsuchen möchten. Dies gilt jedoch auch, nachdem Sie den Dateityp identifiziert haben, da Sie ihn benötigen um herauszufinden, was die Referenzen sind. Dies ist nicht so schlimm, wenn Sie nur ein paar Dateien gleichzeitig bearbeiten, wie es der Browser tut, aber ein Webserver muss Hunderte oder Tausende von Anfragen gleichzeitig bearbeiten. Das summiert sich und wenn es zu weit geht, kann es die Dinge tatsächlich mehr verlangsamen, als dies bei mehreren Anfragen der Fall wäre. Wenn Sie jemals einen Link von Slashdot oder ähnlichen Websites aus besucht haben, um festzustellen, dass der Server aufgrund der hohen Auslastung quälend langsam ist, haben Sie dieses Prinzip in Aktion gesehen.
Das dritte Problem besteht darin, dass der Server nicht weiß, was Sie mit der Datei tun möchten . Ein Browser benötigt möglicherweise die Dateien, auf die im HTML verwiesen wird, jedoch möglicherweise nicht, abhängig vom genauen Kontext, in dem die Datei ausgeführt wird. Das wäre komplex genug, aber das Web bietet mehr als nur Browser: Zwischen Spinnen, Feed-Aggregatoren und Seiten-Scraping-Mashups gibt es viele Arten von Benutzeragenten, bei denen die Dateien nicht im HTML-Code referenziert werden müssen : Sie Kümmere dich nur um den HTML-Code. Das Senden dieser anderen Dateien an solche Benutzeragenten würde nur Bandbreite verschwenden.
Das Fazit ist, dass das Herausfinden dieser Abhängigkeiten auf der Serverseite mehr Mühe bereitet, als es wert ist . Stattdessen lassen sie den Kunden herausfinden, was er benötigt.
quelle