Nach dem letzten Blogbeitrag zu meinem neuen Render Hook zum Einbinden von Bildern in Hugo habe ich von SuperTux88 wertvolle Rückmeldungen bekommen. Vielen Dank dafür. 👍

Update

Update 1: Den Shortcode und den Hook gibt es hier zum herunterladen, siehe unten.

Update 2 (04.04.2023): Es gibt wieder einen verbesserten Render Hook, der sich am Ursprungsformat eines Fotos orientiert, nur auf Webp für die Bildvarianten ausgelegt ist und somit sehr viel schneller ist und viel weniger Daten produziert, siehe hier.

Die Rückmeldungen

Die Rückmeldungen sind im Einzelnen aufgelistet…

Mehr Monitor

  • Wenn jemand einen 4k Monitor hat, dann freut er sich über Bilder, die höher aufgelöst sind als nur 816 Pixel in der Breite.

Meine Lösung: Wenn das Originalbild breiter ist als 1632 Pixel, dann wird zusätzlich noch ein hoch aufgelöstes Bild erzeugt mit 1632 Pixel Breite. In meinem Blog trifft das z. B. auf einzelne Fotos oder Panoramabilder zu, die mindestens 2000 Pixel breit sind.

WebP und JPG

  • Hugo kann man anweisen, die Varianten des Originalbilds immer als WebP zu erzeugen, auch wenn das Original ein anderes Format hat.
  • Safari auf Mac OS kann noch nicht mit WebP umgehen. Korrektur: Nur Safari auf alten Mac OS Systemen kann kein WebP. Es hängt wohl vom Betriebssystem ab und das aktuelle Mac OS kann WebP.

Lösung: Für alle Bilder werden jetzt kleine Bildvarianten in den Formaten JPG und WebP erzeugt. Beide Dateiformate werden zur Verfügung gestellt. WebP ist der Standard und JPG das Fallback (z. B. für Safari und Mac OS).

4k “simulieren”

Im Browser auf 200 % zoomen, dann bekommt man auch die große Bildvariante geliefert, wenn sie vorhanden ist, siehe nächster Abschnitt.

Wie der neue Render Hook arbeitet

Und aus all den Vorschlägen und viel Arbeit ist nun das neue Render Hook entstanden, das wie folgt arbeitet (und damit etwas anders als bisher):

  • Ist das Originalbild eine .webp-Datei, dann wird dieses konvertiert und eine .jpg-Datei erzeugt, sodass beide Formate vorliegen.
  • Ist das Originalbild eine .jpg-Datei, dann wird dieses konvertiert und eine .webp-Datei erzeugt, sodass beide Formate vorliegen.
  • Ist das Originalbild eine andere von Hugo unterstützte Datei, dann wird diese konvertiert und sowohl eine .webp- als auch in eine .jpg-Datei erzeugt, sodass beide Formate vorliegen.
  • Ist das Originalbild 816 Pixel breit oder breiter, dann wird ein srcset erzeugt für die Breiten 360, 500, 816 und optional bei Bildern über 1632 Pixeln noch zusätzlich 1632 Pixel Breite.
  • Ist das Originalbild kleiner als 816 Pixel, dann wird nur das Originalbild ohne srcset in der Seite eingebunden und es findet keine Verlinkung statt und es werden keine kleinen Bildvarianten erzeugt.
  • Ist das Originalbild breiter als 1000 Pixel, dann wird um die einbegundene verkleinerte Variante herum ein Link auf das Originalbild gesetzt.
  • In allen Fällen wird das Bild per picture-Element eingebunden. Dieses enthält immer als Voreinstellung per source-Element (Dokumentation) alle Bildgrößen im .webp-Format und als Fallback im img-Element alle Bildgrößen im .jpg-Format.
  • Liegt das Bild nicht im Page Bundle, dann wird es ohne irgendwelche Zusätze per img-Element eingebunden.
  • Bilder werden immer per Lazy loading eingebunden.

Vorteile der neuen Variante des Render Hooks

Ich kann für die Originalbilder alle Formate verwenden, die Hugo konvertieren kann. Das sind bmp, gif, jpeg, jpg, png, tif, tiff, webp. Alle kleinen Bildvarianten werden jedoch im JPG- und WebP-Format zur Verfügung gestellt.

Beispiele

So sieht es z. B. aus, wenn das Originalbild eine circa 5000 Pixel breites WebP-Datei ist (Pfade und Dateinamen auf das Wesentliche gekürzt):

<figure class="image-caption">
    <a href="lala.webp">
        <picture>
            <source type="image/webp"
                srcset="360x.webp 360w,500x.webp 500w,816x.webp 816w, 1632x.webp 1632w"
                sizes="(max-width: 424px) 360px, (max-width: 596px) 500px, (min-width: 565px) 816px,(min-width: 1200px) 1632px"
            />
            <img alt="lala"
                    srcset="360x.jpg 360w, 500x.jpg 500w, 816x.jpg 816w, 1632x.jpg 1632w,"
                    sizes="(max-width: 424px) 360px, (max-width: 596px) 500px, (min-width: 565px) 816px,(min-width: 1200px) 1632px"
                    src="1632x.jpg" title="lala" loading="lazy" />
        </picture>
    </a>
    <figcaption>lala</figcaption>
</figure>

Und so sieht es aus, wenn die Datei schmaler als 816 Pixel ist:

<figure class="image-caption">
    <picture><source type="image/webp" srcset="330x.webp" />
    <img alt="lala" src="lala.jpg" title="lala" loading="lazy" /></picture>
    <figcaption>lala</figcaption>
</figure>

Unschöne Platzverschwendung

Update

29.04.2022: Eindeutig Unfähigkeit 🤪

Mit den genannten Befehlen wird das Ergebnis ins HTML gerendert. Das Bild wird aber schon beim Befehl .Resize generiert. Danke für die Klarstellung.

Durch eine zur Verfügung gestellte Beispielimplementierung von SuperTux88 hab ich einige Dinge über Hugo gelernt, die ich vorher nicht wusste. Bin halt Anwender, kein Programmierer. 🤪 Dadurch konnte ich den Render Hook so umsetzen, wie ich es eigentlich vor hatte.

Zum Beispiel werden jetzt nicht mehr immer alle möglichen Bildgrößen erzeugt sondern nur die benötigten. Für den Blog bedeutet das eine Verkleinerung der genertierten Bilddateien von 700 MiB auf 244 MiB und für das Wiki von 644 MiB auf 355 MiB.

Entweder liegt es an meiner Unfähigkeit oder an Hugo, dass Bildvarianten, die gar nicht verwendet werden und in irgendwelchen If-Bedingungen im Render Hook stehen und gar nicht erfüllt werden, trotzdem jedes Mal erzeugt werden. Stört mich nicht sehr, da sie niemals ausgeliefert werden, aber sie sind da und belegen Speicherplatz. Vielleicht kann ich das in Zukunft noch lösen.

Laut Dokumentation sollte meinem Verständnis nach das Bild erst dann generiert werden, wenn einer dieser “Befehle” auf das Bild ausgeführt wird: Permalink, RelPermalink, Width, Height.

Im Render Hook reicht aber schon so eine Zeile aus, um das Bild zu generieren:

{{- $img_webp := $img.Resize "600x webp" -}}

Wer darüber etwas weiß, darf sich gerne melden. 🙂

Verbesserungen?

Vielleicht wäre es sinnvoller, immer auf die konvertierte jpg-Datei zu verlinken. Oder auf die webp-Datei? Kann man das irgendwie so in HTML einbinden, dass sich der Browser je nach Fähigkeit selbst aussuche, welchen Link zu welchem Ziel er wählt?

Nützliches zum Picture-Tag

  • Antwort auf die Frage, ob man ein picture-Element in ein figure-Element stecken darf, siehe hier. Spoiler: Definitiv. Und hier zur weiteren Lektüre dazu.

Shortcode und Hook zum Herunterladen

Das .txt am Ende muss entfernt werden.