Haben Sie in letzter Zeit in der Developer Console in Chrome eine Warnung wie die folgende gesehen und sich gefragt, was das bedeutet?
(index):34 A Parser-blocking, cross-origin script,
https://paul.kinlan.me/ad-inject.js, is invoked via document.write().
This may be blocked by the browser if the device has poor network connectivity.
Die Kombinierbarkeit ist eine der großen Stärken des Webs. So können wir Drittanbieterdienste ganz einfach integrieren, um tolle neue Produkte zu entwickeln. Einer der Nachteile der Komponentenauswahl ist, dass sie eine gemeinsame Verantwortung für die Nutzerfreundlichkeit impliziert. Eine suboptimale Integration wirkt sich negativ auf die Nutzerfreundlichkeit aus.
Eine bekannte Ursache für eine schlechte Leistung ist die Verwendung von document.write()
auf Seiten, insbesondere bei der Einschleusung von Scripts. So harmlos das folgende Beispiel auch aussieht, kann es für Nutzer zu echten Problemen führen.
document.write('<script src="https://example.com/ad-inject.js"></script>');
Bevor der Browser eine Seite rendern kann, muss er den DOM-Baum erstellen, indem er das HTML-Markup analysiert. Wenn der Parser auf ein Script stößt, muss er anhalten und es ausführen, bevor er mit dem Parsen der HTML-Datei fortfahren kann. Wenn das Script dynamisch ein anderes Script einschleust, muss der Parser noch länger auf den Download der Ressource warten. Dies kann zu einem oder mehreren Netzwerk-Roundtrips führen und die Zeit bis zum ersten Rendern der Seite verzögern.
Bei Nutzern mit langsamen Verbindungen wie 2G kann das dynamische Einfügen externer Skripte über document.write()
dazu führen, dass sich das Anzeigen des Contents der Hauptseite mehrere Sekunden verzögert oder dass Seiten nicht oder sehr langsam geladen werden. Möglicherweise verlässt der Nutzer die Seite dann, noch bevor sie gerendert wurde. Basierend auf der Instrumentierung in Chrome haben wir festgestellt, dass Seiten mit Skripts von Drittanbietern, die über document.write()
eingefügt werden, bei einer 2G-Verbindung in der Regel doppelt so lange zum Laden benötigen wie andere Seiten.
Wir haben Daten aus einem 28-tägigen Feldtest mit 1% der Chrome Stable-Nutzer erhoben, die nur Nutzer mit 2G-Verbindungen umfasste. Wir haben festgestellt, dass 7,6% aller Seitenladevorgänge bei 2G mindestens ein websiteübergreifendes Parser-Blockierungs-Script enthielten, das über document.write()
in das Dokument der obersten Ebene eingefügt wurde. Durch das Blockieren des Ladens dieser Scripts konnten wir folgende Verbesserungen erzielen:
- 10% mehr Seitenladevorgänge, bei denen der First Contentful Paint (eine visuelle Bestätigung für den Nutzer, dass die Seite effektiv geladen wird) erreicht wird, 25% mehr Seitenladevorgänge, bei denen der vollständig geparste Status erreicht wird, und 10% weniger Neustarts, was auf eine geringere Frustration der Nutzer hindeutet.
- Reduzierung der durchschnittlichen Zeit bis zur ersten Darstellung von Inhalt um 21% (über eine Sekunde schneller)
- Die durchschnittliche Zeit für das Parsen einer Seite konnte um 38% reduziert werden, was einer Verbesserung von fast sechs Sekunden entspricht. Die Zeit, die vergeht, bis die für den Nutzer wichtigen Informationen angezeigt werden, wurde dadurch drastisch verkürzt.
Auf Grundlage dieser Daten greift Chrome ab Version 55 im Namen aller Nutzer ein, wenn wir dieses bekannte schädliche Muster erkennen. Dazu ändern wir die Verarbeitung von document.write()
in Chrome (siehe Chrome-Status).
Chrome führt die über document.write()
eingeschleusten <script>
-Elemente insbesondere nicht aus, wenn alle der folgenden Bedingungen erfüllt sind:
- Der Nutzer hat eine langsame Verbindung, insbesondere wenn er 2G verwendet. (In Zukunft wird die Änderung möglicherweise auf andere Nutzer mit langsamen Verbindungen ausgeweitet, z. B. auf Nutzer mit langsamer 3G- oder WLAN-Verbindung.)
- Das
document.write()
befindet sich in einem Dokument der obersten Ebene. Die Maßnahme gilt nicht für document.written-Scripts in Iframes, da sie das Rendern der Hauptseite nicht blockieren. - Das Script in
document.write()
blockiert den Parser. Scripts mit den Attributenasync
oderdefer
werden weiterhin ausgeführt. - Das Script wird nicht auf derselben Website gehostet. Mit anderen Worten: Chrome greift nicht bei Scripts mit einem übereinstimmenden eTLD+1 ein (z.B. ein Script, das auf js.beispiel.de gehostet und auf www.beispiel.de eingefügt wurde).
- Das Script befindet sich nicht bereits im HTTP-Cache des Browsers. Für Scripts im Cache kommt es nicht zu einer Netzwerkverzögerung und sie werden trotzdem ausgeführt.
- Die Anfrage für die Seite ist kein Neuladen. Chrome greift nicht ein, wenn der Nutzer ein Neuladen ausgelöst hat, und führt die Seite wie gewohnt aus.
In Snippets von Drittanbietern wird manchmal document.write()
verwendet, um Scripts zu laden.
Glücklicherweise bieten die meisten Drittanbieter alternative asynchrone Lademethoden, mit denen Drittanbieter-Scripts geladen werden können, ohne dass die Anzeige des restlichen Inhalts auf der Seite blockiert wird.
Wie kann ich das beheben?
Die einfache Antwort lautet: Scripts nicht mit document.write()
einschleusen. Wir pflegen eine Reihe von bekannten Diensten für die Unterstützung asynchroner Loader, die Sie regelmäßig prüfen sollten.
Wenn Ihr Anbieter nicht in der Liste aufgeführt ist, aber asynchrones Script-Laden unterstützt, teilen Sie uns das bitte mit, damit wir die Seite aktualisieren können.
Wenn Ihr Anbieter das asynchrone Laden von Scripts auf Ihrer Seite nicht unterstützt, wenden Sie sich bitte an ihn und teilen Sie uns und ihm mit, wie sich die Änderung auf ihn auswirkt.
Wenn dein Anbieter dir ein Snippet mit document.write()
zur Verfügung stellt, kannst du dem Script-Element möglicherweise das Attribut async
hinzufügen oder die Script-Elemente mit DOM-APIs wie document.appendChild()
oder parentNode.insertBefore()
hinzufügen.
So erkennen Sie, ob Ihre Website betroffen ist
Es gibt eine große Anzahl von Kriterien, die bestimmen, ob die Einschränkung angewendet wird. Woher wissen Sie also, ob Sie betroffen sind?
Erkennen, wenn ein Nutzer 2G nutzt
Um die potenziellen Auswirkungen dieser Änderung zu verstehen, müssen Sie zuerst wissen, wie viele Ihrer Nutzer 2G nutzen. Mit der Network Information API, die in Chrome verfügbar ist, können Sie den aktuellen Netzwerktyp und die aktuelle Netzwerkgeschwindigkeit des Nutzers ermitteln und dann eine Benachrichtigung an Ihre Analyse- oder RUM-Systeme (Real User Metrics) senden.
if(navigator.connection &&
navigator.connection.type === 'cellular' &&
navigator.connection.downlinkMax <= 0.115) {
// Notify your service to indicate that you might be affected by this restriction.
}
Warnungen in den Chrome DevTools erfassen
Seit Chrome 53 werden in den Entwicklertools Warnungen für problematische document.write()
-Anweisungen ausgegeben. Wenn eine document.write()
-Anfrage die Kriterien 2 bis 5 erfüllt (Chrome ignoriert die Verbindungskriterien beim Senden dieser Warnung), sieht sie in etwa so aus:
Es ist zwar hilfreich, Warnungen in den Chrome-Entwicklertools zu sehen, aber wie können Sie diese Probleme in großem Umfang erkennen? Sie können nach HTTP-Headern suchen, die an Ihren Server gesendet werden, wenn die Intervention erfolgt.
HTTP-Header der Scriptressource prüfen
Wenn ein über document.write
eingefügtes Script blockiert wurde, sendet Chrome den folgenden Header an die angeforderte Ressource:
Intervention: <https://shorturl/relevant/spec>;
Wenn ein über document.write
eingefügtes Script gefunden wird und unter verschiedenen Umständen blockiert werden könnte, sendet Chrome möglicherweise Folgendes:
Intervention: <https://shorturl/relevant/spec>; level="warning"
Der Header für die Intervention wird als Teil der GET-Anfrage für das Script gesendet (bei einer tatsächlichen Intervention asynchron).
Was wird die Zukunft bringen?
Der ursprüngliche Plan sieht vor, diese Maßnahme auszuführen, wenn wir feststellen, dass die Kriterien erfüllt sind. In Chrome 53 wurde in der Entwicklerkonsole nur eine Warnung angezeigt. (Die Betaphase begann im Juli 2016. Wir gehen davon aus, dass die Stable-Version im September 2016 für alle Nutzer verfügbar sein wird.)
Wir werden eingreifen, um injizierte Scripts für 2G-Nutzer voraussichtlich ab Chrome 54 zu blockieren. Diese Version wird voraussichtlich Mitte Oktober 2016 als stabile Version für alle Nutzer veröffentlicht. Weitere Informationen finden Sie im Chrome-Status.
Mit der Zeit möchten wir eingreifen, wenn ein Nutzer eine langsame Verbindung hat (z. B. eine langsame 3G- oder WLAN-Verbindung). Folgen Sie diesem Chrome-Statuseintrag.
Möchten Sie mehr erfahren?
Weitere Informationen finden Sie in den folgenden Ressourcen: