Warum fordern Browser Skripte bei Nicht-200-Antworten erneut an?

8

Speichern Sie den folgenden HTML-Code als lokale Datei. Etwas wie /tmp/foo.html , dann öffne das in Firefox (ich bin auf 49.0.2)

%Vor%

Ich habe keinen Server, der auf Port 1234 ausgeführt wird, daher werden die Anforderungen nicht einmal erfolgreich verbunden.

Das Verhalten, das ich hier erwarten würde, ist, dass alle Anfragen fehlschlagen und damit erledigt werden.

Was eigentlich in Firefox passiert, ist, dass alle fünf .js-Dateien parallel angefordert werden, sie keine Verbindung herstellen, dann werden die letzten vier in der Serie erneut angefordert. Wie so:

Warum?

Wenn ich einen Server auf 1234 boote, der immer 404s ist, ist das Verhalten dasselbe.

Dieses besondere Beispiel reproduziert nicht das gleiche Verhalten in Chrome, aber andere ähnliche Beispiele sind, wie ich ursprünglich auf dieses Verhalten stieß.

BEARBEITEN : So habe ich das getestet, wenn es auch 404 gibt.

%Vor%

Dann lud Firefox neu. Es zeigt dies:

Der Server sieht tatsächlich alle diese Anfragen (die ersten 5 kommen außer Betrieb, weil sie parallel angefordert werden, aber die letzten 4 sind immer b, c, d, e, da sie in der Serie erneut angefordert werden) .

%Vor%     
Jamie Wong 02.11.2016, 02:05
quelle

1 Antwort

10

Dies hat mit Kantenfällen zu tun, die beim parallelen Laden von Ressourcen auftreten können, wobei JavaScript das Laden anderer Ressourcen blockieren soll.

Dieses Verhalten wird deutlicher, wenn Sie den Fehlerantworten eine Verzögerung hinzufügen. Hier ist ein Screenshot des Firefox-Netzwerk-Panels mit einer Verzögerung von 1 Sekunde, die jeder Anfrage hinzugefügt wird.

Wie wir sehen können, wurden alle 5 Skripte parallel angefordert, wie moderne Browser tun , Ladezeiten zu reduzieren.

Mit Ausnahme des ersten wurden jedoch die Skripte, die einen 404 zurückgaben, erneut angefordert, nicht parallel, sondern in Serie. Dies ist fast sicher, Rückwärtskompatibilität mit einigen Edge-Fällen mit dem Verhalten des alten Browsers aufrechtzuerhalten.

In der Vergangenheit würde ein Browser jeweils ein Skript laden und ausführen. Der moderne Browser lädt sie parallel, während die Ausführungsreihenfolge beibehalten wird.

Warum könnte das so sein?

Stellen Sie sich vor, ob die erste Skriptanfrage den Anwendungsstatus geändert hat, vielleicht ein Cookie gesetzt oder etwas, um weitere Anfragen zu authentifizieren. Mit dem neuen parallelen Laden werden diese Skripts angefordert, bevor dieser Status geändert wurde. Wenn die Webanwendung gut genug entworfen ist, wird ein Fehler ausgelöst.

Die einzige Möglichkeit, sicherzustellen, dass die anderen Ressourcen nicht fehlerhaft waren, weil das Skript keine Möglichkeit hatte, den Status vor der Anforderung zu ändern, besteht darin, die Ressourcen erneut erneut anzufordern.

Tatsächlich ist dieses erneut anfordernde Verhalten nicht nur auf Skripts beschränkt, sondern zeigt auch, dass der Fehler nach einem parallel geladenen Skript-Tag auftritt.

Da diese Bilder möglicherweise nicht geladen wurden, weil ein vorheriges Skript nicht zuerst ausgeführt wurde, werden sie möglicherweise alle parallel erneut angefordert.

Interessanterweise kann ich in der Spezifikation nichts direkt darüber finden, aber dieser Abschnitt von

  

Wenn bei klassischen Skripten das Attribut async vorhanden ist, wird das klassische Skript parallel zum Parsen abgerufen und ausgewertet, sobald es verfügbar ist (möglicherweise vor Abschluss des Parsings). Wenn das Attribut async nicht vorhanden ist, das Attribut defer jedoch vorhanden ist, wird das klassische Skript parallel abgerufen und ausgewertet, wenn die Seite die Analyse beendet hat. Wenn keines der Attribute vorhanden ist, wird das Skript sofort abgerufen und ausgewertet. Das Parsing wird blockiert, bis beide vollständig sind.

Wenn das Parsing tatsächlich blockiert wurde, dann sollten die folgenden Skript-Tags und Bilder nicht gelesen worden sein, damit sie geladen werden können. Ich vermute, dass die Browser dieses Problem abstimmen, indem sie die folgenden Tags erst nach der Ausführung im DOM verfügbar machen.

Hinweis:

Das genaue Verhalten, das Sie in diesen Fällen sehen, kann ein wenig variieren. Nur die Ressourcen, die tatsächlich parallel zu einem Skript angefordert wurden, werden tatsächlich neu geladen. Wenn ein Bild nachher fehlerhaft ist, aber während des Ladens eines Skripts nicht angefordert wurde, muss es nicht erneut angefordert werden. Darüber hinaus scheint es, dass Chrome dieses Verhalten nur dann auslöst, wenn das Skript, das den Status des potenziellen Status ändert, nicht ausgibt. Firefox löst dieses Verhalten jedoch aus, selbst wenn ein Fehler auftritt.

    
Alexander O'Mara 05.11.2016, 04:37
quelle

Tags und Links