Hugo Alpha: Zu welchem Zeitpunkt werden Dateien genau geladen? (am Bsp. Bilder)

Guten Abend.

Kurze Verwirrung zum Ladezeitpunkt von Dateien:

Zu welchem Zeitpunkt beginnt der Browser typischerweise, dynamisch erstellte größere Dateien zu laden?

Beispiel Bilder:

Startet der Download bereits mit createElement

let Bild = document.createElement("img");
Bild.src = "meineQuelle.jpg";

oder erst, wenn das Bild explizit ins DOM eingefügt wird

document.body.appendChild(Bild);

... Wenn zweiteres der Fall: Wie kann ich den Browser überzeugen, Bilder bereits mit createElement vorbereitend zu laden?

Vielen Dank und gute Nacht,

Hugo.

  1. <Nachtrag>

    ...entschuldigung, vielleicht sollte ich das noch präziser formulieren:

    Wird Bild bereits mit createElement geladen, und (vor allem) löst dann das load Event aus, wenn der Download erfolgreich beendet wurde?

    </Nachtrag>

  2. Hallo Hugo,

    TIL: es gibt die - relative neue, aber in den Evergreen-Browsern verfügbare - Methode decode.

    Die gibt Dir ein Promise zurück, und wenn sich das erfüllt, ist das Image geladen, verfügbar und kann ins DOM eingefügt werden. Wenn das Bild z.B. am Server nicht vorhanden ist oder die Netzwerkverbindung abbricht, wird das Promise zurückgewiesen.

    D.h. bevor Du decode() aufrufst, musst Du prüfen ob sie überhaupt vorhanden ist. Wenn nicht, dann kannst Du ein hyper-eager Loading nicht durchführen und brauchst eine Ersatzstrategie. Das ist im Web nun mal so. Wenn moderne Funktionen verfügbar sind, kannst Du dem User mehr Freude machen. Wenn nicht, dann nicht. Progressive Enhancing. Oder Rückfall auf alte Techniken, wenn möglich und bezahlbar.

    Ohne den Aufruf von decode beginnt der Ladevorgang frühestens mit dem Einfügen ins DOM. Dafür finde ich zwar auf die Schnelle keinen Beleg, aber anders kann es nicht sein. Vor allem das load Event darf erst gefeuert werden, wenn das Image im DOM ist, weil sonst das ganze Bubbling nicht greift (und weil decode sonst überhaupt keinen Sinn ergeben würde).

    Ich schrieb „beginnt der Ladevorgang frühestens“. Was das bedeutet, hängt von den Umständen ab.

    • Das Image hat den loading="lazy" Parameter gesetzt -> Das Bild wird erst geladen wenn es in den Bereich der Sichtbarkeit kommt.
    • Die Bildquelle befindet sich im Cache -> Der Request wird vom Browser sofort beantwortet. Im Cache kann er sein, weil das Bild schonmal abgerufen wurde, oder weil es vom Server mit HTTP/2 Techniken schon gesendet wurde.
    • Die maximale Anzahl paralleler Serverrequests ist noch nicht erreicht -> der GET Request wird sofort gesendet.
    • Die maximale Anzahl paralleler Serverrequests ist erreicht -> der GET Request wird gequeued. Sobald ein offener Request erledigt ist, wird der nächste Eintrag aus der Queue geholt.

    Ich kann Dir nicht genau sagen, wie sich lazy Loading auswirkt wenn das Bild schon im Cache ist. Ich würde mutmaßen, dass ein gecachtes Bild, das außerhalb des Viewports ist, nicht angeschaut wird und das load Event erst feuert wenn das Bild in den Viewport kommt. Das wäre konsistent zu nicht gecachten Bildern.

    Wenn Du es genauer wissen willst, dies die HTML Spec. Ich habe sie jetzt nur überflogen (und damit immerhin decode entdeckt, das kannte ich bisher nicht).

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hey Rolf,

      Danke für deine Ausführungen.

      Hab weiter zum Thema decode recherchiert - und bin auf diesen sehr hilfreichen Artikel gestoßen.

      Sowohl load als auch decode scheinen die Bilder schon vor append zu laden, load blockiert dabei allerdings den Main Thread, weil die Bilder erst dekodiert werden müssen.

      When loading an image with JavaScript in the way we actually do, the image.onload handler guarantees that trying to use the image is going to work. At this time the image is not decoded. With the first time using the image data we usually get a delay to decoding overhead. So after inserting an image into the DOM a paint event occurs and this causes a synchronous decode of the image in the main thread. As a result the main thread is blocked.