Wenn wir über Frontend-Performance sprechen, denken wir an Dinge wie Konkatenation, Minifizierung, Caching oder Gzipping von Assets auf dem Server, damit die Seite schneller geladen wird und Benutzer ihre Ziele so schnell wie möglich erreichen können.
Das Vorabrufen von Ressourcen ist eine weitere Technik zur Leistungssteigerung. Wir können sie verwenden, um dem Browser mitzuteilen, welche Assets der Benutzer möglicherweise in Zukunft benötigt – noch bevor er sie überhaupt benötigt.
Pre-fetching ist eine Möglichkeit, dem Browser Hinweise auf Ressourcen zu geben, die definitiv in Zukunft verwendet werden oder werden könnten. Einige Hinweise beziehen sich auf die aktuelle Seite, andere auf mögliche zukünftige Seiten.
Als Entwickler kennen wir unsere Anwendungen besser als der Browser. Wir können diese Informationen nutzen, um den Browser über Kernressourcen zu informieren.
Diese Praxis, zu erraten, was Benutzer benötigen, bevor sie es brauchen, wurde als Prebrowsing bezeichnet. Es handelt sich jedoch nicht um eine einzelne Technik, sondern sie gliedert sich in eine Reihe verschiedener Techniken: dns-prefetch, , das Standard-subresourceprefetch, preconnect und prerender.
DNS-Prefetching
Dies informiert den Client darüber, dass wir später Assets von einer bestimmten URL benötigen werden, damit der Browser die DNS-Auflösung so schnell wie möglich durchführen kann. Sagen wir, wir benötigen eine Ressource wie ein Bild oder eine Audiodatei von der URL example.com. Im <head> des Dokuments würden wir schreiben
<link rel="dns-prefetch" href="//example.com">
Wenn wir dann eine Datei davon anfordern, müssen wir nicht mehr auf die DNS-Auflösung warten. Dies ist besonders nützlich, wenn wir Code von Drittanbietern oder Ressourcen von sozialen Netzwerken verwenden, von denen wir möglicherweise ein Widget über ein <script> laden.
In seinem epischen Beitrag zur Frontend-Performance schlägt Harry Roberts vor, diese Technik zu verwenden
Diese einfache Zeile weist unterstützende Browser an, mit dem Vorabrufen der DNS für diese Domäne einen Bruchteil einer Sekunde bevor sie tatsächlich benötigt wird zu beginnen. Das bedeutet, dass der DNS-Lookup-Prozess bereits im Gange ist, wenn der Browser auf das Skriptelement trifft, das das Widget tatsächlich anfordert. Es gibt dem Browser einfach einen kleinen Vorsprung.
Dies mag wie eine so geringfügige Leistungsverbesserung erscheinen, dass sie nicht sehr wichtig ist, aber das ist nicht unbedingt der Fall – Chrome macht ständig etwas Ähnliches. Es löst die DNS automatisch vorab auf (und manchmal sogar die Seite vorab), wenn Sie nur einen kleinen Teil der Domäne in die Adressleiste eingeben, wodurch Millisekunden bei jeder Anfrage eingespart werden.
Preconnect
Ähnlich wie bei der DNS-Prefetch-Methode löst Preconnect die DNS auf, aber es führt auch den TCP-Handshake und die optionale TLS-Aushandlung durch. Es kann wie folgt verwendet werden
<link rel="preconnect" href="https://css-tricks.de">
Für weitere Informationen hat Ilya Grigorik einen großartigen Beitrag über diesen praktischen Ressourcenhinweis verfasst.
Moderne Browser tun ihr Bestes, um vorherzusagen, welche Verbindungen die Website vor der eigentlichen Anfrage benötigen wird. Durch die frühzeitige Einleitung von „Preconnects“ kann der Browser die notwendigen Sockets im Voraus einrichten und die kostspieligen DNS-, TCP- und TLS-Roundtrips aus dem kritischen Pfad der eigentlichen Anfrage eliminieren. Allerdings können moderne Browser, so intelligent sie auch sind, nicht zuverlässig alle Preconnect-Ziele für jede Website vorhersagen.
Die gute Nachricht ist, dass wir endlich dem Browser helfen können; wir können dem Browser mitteilen, welche Sockets wir benötigen werden, bevor die eigentlichen Anfragen gestellt werden, über den neuen Preconnect-Hinweis, der in Firefox 39 und Chrome 46 verfügbar ist!
Prefetching
Wenn wir sicher sind, dass eine bestimmte Ressource in Zukunft benötigt wird, können wir den Browser bitten, diesen Artikel anzufordern und ihn für spätere Referenzen im Cache zu speichern. Zum Beispiel ein Bild oder ein Skript oder wirklich alles, was vom Browser gecached werden kann.
<link rel="prefetch" href="image.png">
Im Gegensatz zu DNS-Prefetching fordern wir diese Ressource tatsächlich an, laden sie herunter und speichern sie im Cache. Dies hängt jedoch von einer Reihe von Bedingungen ab, da Prefetching vom Browser ignoriert werden kann. Beispielsweise kann ein Client die Anforderung einer großen Schriftdatei über ein langsames Netzwerk abbrechen. Firefox ruft nur dann Ressourcen im Voraus ab, wenn „der Browser im Leerlauf ist“.
Wie Bram Stein in seinem Beitrag zu diesem Thema erklärt, könnte dies enorme Leistungsvorteile für Webfonts haben. Derzeit müssen Schriftdateien auf die Konstruktion von DOM und CSSOM warten, bevor sie überhaupt heruntergeladen werden. Wenn wir sie jedoch vorab abrufen, kann dieser Engpass leicht umgangen werden.
Hinweis: Obwohl das Vorabrufen von Assets früher schwierig zu testen war, zeigen Chrome und Firefox jetzt vorab abgerufene Ressourcen im Network-Panel an. Außerdem ist es hilfreich zu bedenken, dass es für Link-Prefetching keine Same-Origin-Beschränkung gibt.
Subressourcen (siehe Hinweis)
Eine weitere Prefetching-Technik hilft bei der Identifizierung der Ressourcen mit der höchsten Priorität, die vor den vorab abgerufenen Elementen angefordert werden sollten. Zum Beispiel könnten wir in Chrome und Opera Folgendes zum head unseres Dokuments hinzufügen
<link rel="subresource" href="styles.css">
Laut den Chromium-Dokumenten funktioniert es so
„LINK rel=subresource“ bietet einen neuen Link-Relationstyp mit anderer Semantik als LINK rel=prefetch. Während rel=prefetch einen Download von Ressourcen mit niedriger Priorität für nachfolgende Seiten bietet, ermöglicht rel=subresource das frühzeitige Laden von Ressourcen innerhalb der aktuellen Seite.
Wenn die Ressource also für die aktuelle Seite benötigt wird oder so schnell wie möglich benötigt wird, dann ist es wahrscheinlich am besten, subresource zu verwenden, andernfalls bleiben Sie bei prefetch.
Seiten vorab rendern
Dies ist die Atombombe, da prerender uns die Möglichkeit gibt, alle Assets eines bestimmten Dokuments im Voraus zu laden, wie zum Beispiel
<link rel="prerender" href="https://css-tricks.de">
Steve Souders hat eine großartige Erklärung zu dieser Technik verfasst.
Dies ist, als würde man die URL in einem versteckten Tab öffnen – alle Ressourcen werden heruntergeladen, das DOM wird erstellt, die Seite wird layoutet, die CSS wird angewendet, das JavaScript wird ausgeführt usw. Wenn der Benutzer zur angegebenen
hrefnavigiert, wird die versteckte Seite eingeblendet, sodass sie sofort geladen zu werden scheint. Google Suche hat diese Funktion seit Jahren unter dem Namen Instant Pages. Microsoft hat kürzlich angekündigt, Prerender auf ähnliche Weise in Bing auf IE11 zu verwenden.
Aber Vorsicht! Sie sollten wahrscheinlich sicher sein, dass der Benutzer auf diesen Link klickt, sonst lädt der Client alle notwendigen Assets zum Rendern der Seite ohne Grund herunter.
Souders fährt fort
Wie bei jeder dieser antizipatorischen Arbeiten besteht das Risiko, dass die Vorhersage falsch ist. Wenn die antizipatorische Arbeit teuer ist (z. B. die CPU von anderen Prozessen stiehlt, Akku verbraucht oder Bandbreite verschwendet), ist Vorsicht geboten. Es scheint schwierig zu sein, vorherzusagen, zu welcher Seite Benutzer als nächstes wechseln werden, aber Szenarien mit hoher Sicherheit existieren.
- Wenn der Benutzer eine Suche mit einem offensichtlichen Ergebnis durchgeführt hat, wird die Ergebnisübersichtsseite wahrscheinlich als nächstes geladen.
- Wenn der Benutzer zu einer Anmeldeseite navigiert hat, kommt wahrscheinlich als nächstes die angemeldete Seite.
- Wenn der Benutzer einen mehrseitigen Artikel oder eine paginierte Ergebnismenge liest, ist die Seite nach der aktuellen Seite wahrscheinlich die nächste.
Schließlich kann die Page Visibility API verwendet werden, um zu verhindern, dass Skripte ausgeführt werden, bevor sie auf dem Bildschirm des Benutzers angezeigt werden.
OK, mit diesen Designüberlegungen aus dem Weg können wir über zukünftige Ergänzungen zur Spezifikation sprechen, die ebenfalls von Interesse sein könnten.
Zukünftige Option: Preloading
Eine neue Spezifikation namens preload schlägt vor, dass es manchmal am besten ist, ein Asset **immer** herunterzuladen, unabhängig davon, ob der Browser dies für eine gute Idee hält oder nicht. Im Gegensatz zum Vorabrufen von Assets, das ignoriert werden kann, **müssen** vorab geladene Assets vom Browser angefordert werden.
<link rel="preload" href="image.png">
Obwohl Preloading derzeit von keinem Browser unterstützt wird, ist die Idee dahinter sicherlich interessant.
Zusammenfassung
Vorauszusehen, was unsere Benutzer als nächstes tun werden, ist schwierig und erfordert sicherlich viel Planung und Tests. Aber die Leistungsvorteile sind es definitiv wert, verfolgt zu werden. Wenn wir bereit sind, mit diesen Prefetching-Techniken zu experimentieren, werden wir die Benutzererfahrung sicherlich spürbar verbessern.
Endlich einige schnelle und aktuelle Dokumentation dazu. Danke!
Tatsächlich habe ich vor einiger Zeit etwas Ähnliches gefragt, aber mit „unangemessenen“ Begriffen, denke ich.
Einfach ausgedrückt: Nehmen wir an, ich habe ein „Lade…“-Bild auf meiner Website, vielleicht zusammen mit einem Hintergrundkachel-Bild, nichts Besonderes.
Gibt es eine Möglichkeit, zu sagen: „Hey, lade diese Dinge in den **6 Top-Plätzen der parallelen Anfragen** herunter“?
Toller Artikel Robin. Danke.
Leider ist
<link rel="subresource"…nicht so nützlich, wie man denken könnte…In Chrome erhalten Subressourcen, die auf diese Weise signalisiert werden, standardmäßig eine sehr niedrige Download-Priorität (https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp&q=LinkSubresource&sq=package:chromium&type=cs&l=122).
Wenn der Browser sie auf normalem Wege entdeckt, sollten sie entsprechend neu priorisiert werden.
Wenn Preload vollständig unterstützt wird, sollte sich der Bedarf an
rel=subresourcehoffentlich erübrigen.Ich denke,
prerenderundsubresourcesind wirklich großartig. Ich würde es vorziehen, nur diese zu implementieren, weil ich davon ausgehe, dass sie mich nicht zu sehr zum Nachdenken anregen.Das gefällt mir wirklich gut! Ich habe nach etwas anderem gesucht, um die Leistung der Website zu steigern.
Die meisten von uns haben wahrscheinlich schon von diesen Attributen gehört. Das Problem ist die Akzeptanz und ob wir sie verwenden können oder nicht. Eine detaillierte Liste, ob sie in jedem Browser verwendbar sind, wäre der Schlüssel zu diesem Artikel. Danke fürs Schreiben!
Die folgende Tabelle enthält Informationen zur Browserunterstützung
https://en.wikipedia.org/wiki/Link_prefetching#Browser_support
Die meisten von uns haben wahrscheinlich schon von http://caniuse.com Ben gehört. LOL
LOL genau mein Punkt! Diese Sachen werden kaum unterstützt. Jeder, der die Spezifikationsupdates aufmerksam verfolgt, hat kein Leben, weiß, dass diese existieren. Die Unterstützung ist das Problem.
Ich wusste nichts von den meisten dieser Dinge, das ist großartig. Ich vermute, wenn
prerenderverwendet wird, muss der Server bei einem Klick auf den Link eine 304 zurückgeben? Oder prüft er überhaupt nicht mit dem Server?Sie haben
preconnectnicht erwähnt, das in Chrome 46 und Firefox 39 verfügbar ist – https://www.igvita.com/2015/08/17/eliminating-roundtrips-with-preconnect/Danke, Joseph! Ich habe den Beitrag gerade mit diesem Ressourcenhinweis aktualisiert.
@Joseph Scott
+1!
Ich habe bemerkt, dass der DNS-Prefetch protokollrelativ ist (
//example.com). Gibt es dafür einen bestimmten Grund, dies im Hinterkopf behaltend?Ich habe ein kleines JavaScript-Dienstprogramm geschrieben, das bei der Verwendung von preconnect, prefetch und prerender hilft: https://github.com/schliflo/BoostR
Nun, einerseits habe ich hier gelernt, dass wir HTML-Deklarationen für Pre-dies und Pre-das verwenden können, andererseits würde ich sagen, dass es immer noch als vorteilhaft angesehen wird, wenn wir Skripte verwenden.
Die offensichtliche Tatsache, dass der Browser willkürliche Entscheidungen trifft, wenn HTML-Vorverarbeitung verwendet wird, ist sinnvoll. Es ist auch sinnvoll, dass es eine Art Vertrag zwischen Browser und Skript gibt, aber nach meinem Verständnis bleibt der Browser der Schiedsrichter und das Skript gibt einfach Anfragen über die Skript-Engine des Browsers aus, die seine APIs für Skripte verfügbar macht.
Ich habe die Implementierung nur mit HTML durchgeführt und sofortige Ergebnisse in modernen Browsern gesehen. Wenn meine Annahmen richtig sind und wir (wir) weiterhin ermutigt werden, auch Skripte zu verwenden, wie wird die Priorität verwaltet und von was?
Der Browser bleibt der Schiedsrichter, aber welche seiner Zwillingskinder werden bevorzugt und was könnte passieren, wenn der Browser Befehle zur Vorverarbeitung erhält, die widersprüchlich sein könnten. W3C sagt uns nicht viel über den Unterschied bei der Verwendung von Link-Typen.
Das ist erstaunlich. Danke fürs Teilen.
Diese sind großartig, aber wie wirkt sich das auf Dinge wie Google Analytics & Prerender aus? Zählt das als Treffer?