Warum registrieren? Nur als registriertes Mitglied vom ABAKUS Forum hast Du vollen Zugriff auf alle Funktionen unserer Website.

HowTo II: Ladezeiten der Bilder optimieren

Alles zum Thema Google Onebox, Knowledge Graph, Google-Shopping, Hotel- und Flugsuche, Maps, Youtube, News-Suche sowie aktuellen Suchtrends.
supervisior
PostRank 8
PostRank 8
Beiträge: 967
Registriert: 26.06.2006, 09:11

Beitrag von supervisior » 29.08.2018, 11:05

Dieses HowTo hat mit Adsense zwar nix am Hut, aber nachdem ich das erste HowTo auch schon unter Google Adsense veröffentlicht habe, schreib ich das hier rein. Es bleibt aber dem Moderator überlassen, ob er dieses Thema ggf. verschiebt.

Dieses HowTo erfolgt in Anlehnung an das oben schon genannte How To unter: https://www.abakus-internet-marketing.d ... 41455.html und soll um ein Weiteres dazu beitragen die Ladezeiten zu optimieren und damit den Pagespeed Gott ;) besänftigen soll.

Ich muss dem nachfolgenden vorausschicken, dass es eine Unzahl von Möglichkeiten gibt, die die Ladezeiten verbessern können und es gibt auch nahezu unendlich viele Seiten, die sich mit dem Thema beschäftigen. Man muss sich aber dabei im Klaren sein, dass diese Optimierungstipps das Problem in 9 von 10 Fällen nur an der Oberfläche behandeln. Zumeist ist es auch so, dass man nicht nur an 1 Rädchen drehen muss, zumal es universelle, aber auch Software spezifische Maßnahmen gibt. Das entscheidende ist jedoch, dass man systemische Maßnahmen ergreifen muss, um wirklich einen deutlichen Sprung nach vorne machen zu können. Systemisch bedeutet, dass man Server seitig eingreifen muss, was den meisten jedoch verwehrt bleibt. Systemisch bedeutet auch, dass es um das Maximale herausholen zu können, man nur individuell vorgehen kann und jede Seite seine eigenen Anforderungen hat, die von universellen Optimierungen ergänzt werden.

Wovon ich persönlich aber abrate, sind die besonders für Wordpress erhältlichen Plugins, die nicht selten alles nur verschlimmbessern. Nicht generell, aber auch nicht selten.

Darum gehts in diesem HowTo:

Das Thema für Optimierungen ist eigentlich immer das Gleiche und verfolgt immer das gleiche Ziel:

So wenig wie möglich, aber so schnell wie möglich übertragen

Das Thema ist nahezu unendlich. Dieses HowTo muss sich deswegen darauf reduzieren, wie man die Ladezeiten reduziert und dabei die Bilder im Fokus stehen. Dass man Bilder komprimieren muss, um überhaupt die Basis für eine Optimierung zu bekommen, muss man eigentlich nicht erwähnen, aber die erste Opimierung fängt eigentlich damit an, dass man das macht. Als Hintergrundinfo sei angemerkt, dass jeder Browser versucht so viel wie möglich gleichzeitig zu laden, jedoch es je nach Browser Unterschiede gibt, wie viel gleichzeitig geladen wird und kann. Beeinflusst wird das dann noch von der Leistungsstärke eines Gerätes und der verfügbaren Bandbreite und nicht zuletzt vom Umfang an zu ladenden css und js Dateien, die dann auch noch gerendert werden müssen. Vor dem Hintergrund der Unzahl an möglichen Geräten, insbesondere der mobilen Geräte, ist es unerlässlich, dass man das Ladeverhalten so gut wie möglich beeinflussen muss.

Um dieses nun beeinflussen zu können, muss man dem Browser etwas zur Hilfe gehen und sein typisches Verhalten beim Laden von Inhalten zu "korrigieren". Das Ziel ist es also das, was den Seitenaufbau ausbremst beim Laden gewissermaßen hinten dran zu stellen und dabei aber der Gesamtaufbau subjektiv beschleunigt wird und dafür sind Bilder besonders geeignet. Das wirkt sich um so mehr aus, je mehr Bilder auf einer zu ladenden Seite sind.

Der Weg zu diesem Ziel ist so einfach wie effektiv und bedarf nur unwesentlicher Änderungen. Funktionieren tut das auf allen Geräten, bei älteren Browsern und auch jeder Art von Bild

Schritt 1 HTML Code der Bilder:

Vorher:

Code: Alles auswählen

<img src="/Pfad_zum_Bild/bild.jpg" alt="Bezeichnung" width="xxx" height="xxx" />
Nachher:

Code: Alles auswählen

<img src="data&#58;image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAHoAwAALAAAAAABAAEAAAICRAEAOw%3D%3D" data-src="/Pfad_zum_Bild/bild.jpg" alt="Bezeichnung" width="xxx" height="xxx" />
Schritt 2 js Schnipsel einfügen:

Den nachfolgenden Schnipsel 1x vor dem </body> Tag einfügen

Code: Alles auswählen

<script>
function init&#40;&#41; &#123;
    var b = document.getElementsByTagName&#40;"img"&#41;;
    for &#40;var a = 0; a < b.length; a++&#41; &#123;
        if &#40;b&#91;a&#93;.getAttribute&#40;"data-src"&#41;&#41; &#123;
            b&#91;a&#93;.setAttribute&#40;"src", b&#91;a&#93;.getAttribute&#40;"data-src"&#41;&#41;
        &#125;
    &#125;
&#125;
window.onload = init;
</script>
oder optimiert einfügen:

Code: Alles auswählen

<script>function init&#40;&#41; &#123;var b = document.getElementsByTagName&#40;"img"&#41;; for &#40;var a = 0; a < b.length; a++&#41; &#123;  if &#40;b&#91;a&#93;.getAttribute&#40;"data-src"&#41;&#41; &#123;b&#91;a&#93;.setAttribute&#40;"src", b&#91;a&#93;.getAttribute&#40;"data-src"&#41;&#41;&#125;&#125;&#125; window.onload = init;</script>
Schritt 3 Kosmetische Optimierung

Um das Anzeigeverhalten dann auch noch kosmetisch zu optimieren, verpassen wir jedem Bild noch ein paar Style Attribute, wodurch das/die Bild/er einen "Smooth" Charakter bekommen. Ist jedoch optional und kann jeder für sich entscheiden, ob er das will.

Code: Alles auswählen

@-webkit-keyframes fadeIn &#123; from &#123; opacity&#58;0; &#125; to &#123; opacity&#58;1; &#125; &#125;
@-moz-keyframes fadeIn &#123; from &#123; opacity&#58;0; &#125; to &#123; opacity&#58;1; &#125; &#125;
@keyframes fadeIn &#123; from &#123; opacity&#58;0; &#125; to &#123; opacity&#58;1; &#125; &#125;
.fade-in &#123;
    opacity&#58;0;  
    -webkit-animation&#58;fadeIn ease-in 1; 
    -moz-animation&#58;fadeIn ease-in 1;
    animation&#58;fadeIn ease-in 1;

    -webkit-animation-fill-mode&#58;forwards;  
    -moz-animation-fill-mode&#58;forwards;
    animation-fill-mode&#58;forwards;

    -webkit-animation-duration&#58;.30s;
    -moz-animation-duration&#58;.30s;
    animation-duration&#58;.30s;
&#125;

.fade-in &#123;
    -webkit-animation-delay&#58; 0.30s;
    -moz-animation-delay&#58; 0.30s;
    animation-delay&#58; 0.30s;
&#125;
Die oben definierte Klasse im img Tag integrieren.

Code: Alles auswählen

<img class="fade-in" src="data&#58;image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAHoAwAALAAAAAABAAEAAAICRAEAOw%3D%3D" data-src="/Pfad_zum_Bild/bild.jpg" alt="Bezeichnung" width="xxx" height="xxx" />
That's it! Enjoy! ;)

[Nachtrag]

Google hat vor einigen Tagen verkündet in einer der nächsten Chrome Versionen eine fix integrierte "Lazy Load" Funktion zu integrieren, die dann dem bekannten "Above the fold" Problem beikommen soll. Letztendlich soll diese Funktion das bewirken, was zwar auch jetzt schon möglich ist, jedoch nur mit einen enormen manuellen Aufwand. Wenn sich diese angekündigte Funktion dann auch in anderen Browsern durchsetzt, kann man sich viele der zahlreich dokumentieren Optimierungsmaßnahmen ersparen, jedoch darf man diese Funktion nicht als das Maß aller Dinge verstehen, weil der systemische Eingriff dann immer noch fehlt.

Hanzo2012
Community-Manager
Community-Manager
Beiträge: 1693
Registriert: 26.09.2011, 23:31

Beitrag von Hanzo2012 » 29.08.2018, 11:36

Welche Auswirkungen hat das auf die Google Bildersuche? Ich könnte mir vorstellen, dass Bilder dann nicht mehr richtig indexiert werden.

elmex
PostRank 9
PostRank 9
Beiträge: 1014
Registriert: 03.05.2005, 10:09

Beitrag von elmex » 29.08.2018, 11:37

Kleiner Tipp, anstat alle Bilder zu parsen, nur die, welche auch data-src gesetzt haben parsen:

Code: Alles auswählen

var b = document.querySelectorAll&#40;"img&#91;data-src&#93;"&#41;;

supervisior
PostRank 8
PostRank 8
Beiträge: 967
Registriert: 26.06.2006, 09:11

Beitrag von supervisior » 29.08.2018, 12:48

Hanzo2012 hat geschrieben:Welche Auswirkungen hat das auf die Google Bildersuche? Ich könnte mir vorstellen, dass Bilder dann nicht mehr richtig indexiert werden.
Google kann Javascript. Von daher gäbe es keine Einschränkungen und kann auch garantieren, dass das in Bezug auf Google keine negativen Auswirkungen hat. Aktiviertes js wäre aber unabängig davon notwendig.

supervisior
PostRank 8
PostRank 8
Beiträge: 967
Registriert: 26.06.2006, 09:11

Beitrag von supervisior » 29.08.2018, 12:51

elmex hat geschrieben:Kleiner Tipp, anstat alle Bilder zu parsen, nur die, welche auch data-src gesetzt haben parsen:

Code: Alles auswählen

var b = document.querySelectorAll&#40;"img&#91;data-src&#93;"&#41;;
Wenn ein Bild kein data-src hat, passiert ohnehin nix, sprich Bild wird wie gewohnt geladen und angezeigt.

staticweb
PostRank 9
PostRank 9
Beiträge: 1149
Registriert: 04.05.2016, 14:34

Beitrag von staticweb » 29.08.2018, 14:51

> Welche Auswirkungen hat das auf die Google Bildersuche? Ich könnte mir vorstellen, dass Bilder dann nicht mehr richtig indexiert werden.

Der Google Bot benutzt den web rendering service aus Chrome 41. Der ist ES5 kompatibel und sollte mit diesem Code keine Probleme haben.

Solange sich die Bildanzahl noch im 3-stelligen Bereich hält sollte es auch keine zeitlichen Probleme geben.

> Kleiner Tipp, anstat alle Bilder zu parsen, nur die, welche auch data-src gesetzt haben parsen: var b = document.querySelectorAll("img[data-src]");

Bei dieser Methode kann es zu Performance-Problemen kommen, da die Attribut-Suche zeitaufwendiger ist. Jedenfalls bei größeren Dokumenten.

Dann wäre es besser wenn eine eindeutige Klasse vergeben und nach der gesucht wird.

supervisior
PostRank 8
PostRank 8
Beiträge: 967
Registriert: 26.06.2006, 09:11

Beitrag von supervisior » 29.08.2018, 15:00

staticweb hat geschrieben:
Bei dieser Methode kann es zu Performance-Problemen kommen, da die Attribut-Suche zeitaufwendiger ist. Jedenfalls bei größeren Dokumenten.

Dann wäre es besser wenn eine eindeutige Klasse vergeben und nach der gesucht wird.
Einspruch! Ich habe mehr als 2 Millionen Bilder auf 250.000 Seiten verteilt. Von Performance Problemen kann absolut nicht die Rede sein, wobei ich noch nicht mal einen Managed oder Root Server betreibe. Wenn Du was kommentieren oder gar zu kritisieren hast, dann baue Deine Kritik bitte nicht auf theoretischen Phantasien auf. Ansonsten landet das hier wieder bei der Diskussion bei Du einmal mehr den Schwanz einziehst.

staticweb
PostRank 9
PostRank 9
Beiträge: 1149
Registriert: 04.05.2016, 14:34

Beitrag von staticweb » 29.08.2018, 15:12

> Von Performance Problemen kann absolut nicht die Rede sein, wobei ich noch nicht mal einen Managed oder Root Server betreibe.

Dein Problem ist, dass du erst schreibst und dann liest und über den Inhalt nachdenkst.

> Wenn Du was kommentieren oder gar zu kritisieren hast, dann baue Deine Kritik bitte nicht auf theoretischen Phantasien auf.

Dann lese mal nach wo in der Praxis (!) die Unterschiede zwischen getElementsByTagName() und querySelectorAll() liegen.

> Ansonsten landet das hier wieder bei der Diskussion bei Du einmal mehr den Schwanz einziehst.

Zu einer Diskussion gehören mindestens 2 Personen und ich muss dir leider mitteilen, dass ich dafür nicht zur Verfügung stehe.

Das kann sich wieder ändern wenn du dich an reale Fakten hältst und nicht nur deine Meinung durchzusetzen versuchst.

supervisior
PostRank 8
PostRank 8
Beiträge: 967
Registriert: 26.06.2006, 09:11

Beitrag von supervisior » 29.08.2018, 16:26

Wusst' ichs doch, dass Du es vorziehst den Schwanz einzuziehen! ;)

Hanzo2012
Community-Manager
Community-Manager
Beiträge: 1693
Registriert: 26.09.2011, 23:31

Beitrag von Hanzo2012 » 29.08.2018, 16:56

@supervisior: Was hat JavaScript-Performance mit einem Managed- oder Root-Server zu tun?

supervisior
PostRank 8
PostRank 8
Beiträge: 967
Registriert: 26.06.2006, 09:11

Beitrag von supervisior » 29.08.2018, 18:03

Hanzo2012 hat geschrieben:@supervisior: Was hat JavaScript-Performance mit einem Managed- oder Root-Server zu tun?
Nichts! ;) War nur eine Randbemerkung.

nerd
PostRank 10
PostRank 10
Beiträge: 4037
Registriert: 15.02.2005, 04:02

Beitrag von nerd » 29.08.2018, 23:53

Sorry, aber ich verstehe nicht ganz was dieser code bezwecken soll..?

So wie ich das lese geht der code alle bilder durch, laedt die bilder per javascript und setzt sie inline als base64 bild ein. Der code wird mit window.onload so zeitig wie moeglich ausgefuehrt, also auch bevor die seite komplett geladen ist - soweit richtig?

Allerdings heisst das ja nichts anderes, als dass du die parallelen downloads die zu dem zeitpunkt auftreten neu aufteils, indem du die bilder eben (erneut, weil noch vom <img src> schon im download queue?) per javascript anforders. Damit reduzierst du aber keine bandbreite da die bilder ja so oder so irgendwie vom server in den browser kommen muessen. Ob das durch parsen des html codes oder ajax request via javascript passiert ist dabei voellig egal.
Die anzahl an files, die der browser gleichzeitig vom server laedt ist begrenzt, und wenn der download-queue voll ist kommen weitere requests in die warteschlange bis ein download fertig ist.
Wenn du die bilder mit diesem code im queue nach vorne mogelst, dann heisst das ja nur das irgendwas anderes (css? fonts? externe scripte?) im gegenzug spaeter geladen wird.

Mir ist nicht ganz klar wo hierbei der gewinn sein soll, oder welches problem du damit loest?

Edit:
was vielleicht sinn macht ist, die bilder die beim pageload ausserhalb des viewports liegen erstmal zu verzoegern und nur das zu laden was tatsaechlich innerhalb des viewports liegt. Bei jQuery ist das relativ einfach mit dem :visible selector, mit vanilla js ist es etwas komplizierter.

Hanzo2012
Community-Manager
Community-Manager
Beiträge: 1693
Registriert: 26.09.2011, 23:31

Beitrag von Hanzo2012 » 30.08.2018, 07:06

@nerd:
Da hast du was übersehen. Die Bilder werden anfangs nicht geladen. Da steht nicht src=..., sondern data-src=...

Cool wäre es, wenn das Base64-kodierte Bild eine niedrig aufgelöste Version des echten Bildes wäre. Kann sein, dass ModPagespeed sowas kann.

Noch ein Tipp, um nicht das window-Objekt mit globalen Variablen zu „verschmutzen“:
window.onload = function() { ... }
statt
function init() { ... } window.onload = init;

Und noch besser, um mehrere Event-Handler zu ermöglichen (falls schon jemand anderes auf onload wartet):
window.addEventListener('load', function() { ... });

supervisior
PostRank 8
PostRank 8
Beiträge: 967
Registriert: 26.06.2006, 09:11

Beitrag von supervisior » 30.08.2018, 07:36

@nerd

Im Grunde genommen hast Du es verstanden, aber dann doch wieder nicht. Die Antwort auf das, was Du nicht verstehst, steht eigentlich in meiner Einleitung, will das aber nochmal auf einfache Weise erläutern.

Beim Aufruf einer Internet Seite gibt es keine Priorität, was an den Inhalten wann geladen wird. Der Browser versucht einfach so viel wie möglich gleichzeitig zu laden, wobei es nicht nur um das Laden von Inhalten geht, sodern auch um das Rendern von css und js. Gewissermaßen und im übertragenen Sinne stopft sich der Browser so viel wie möglich ins Maul, verschluckt sich aber dabei alles, was er im Maul hat, zu kauen und zu schlucken. Der "Essvorgang" = Ladeverhalten einer Seite wird dadurch verlangsamt. Beim Laden einer Seite blockiert im Grunde genommen das Eine das Andere

Bringt man jetzt den Viewport, bzw. das "Above the fold" und das Nutzerverhalten ins Spiel, führt dieses verlangsamte Ladeverhalten zu vorzeitigen Absprüngen noch bevor die Seite eigentlich geladen ist. Man weiß inzwischen, dass dieses typische Ladeverhalten dazu beiträgt, dass die Absprungraten noch vor dem vollständigen Laden einer Seite eine nicht unwichtige Rolle spielt. Deswegen pocht Google schon seit längerem auf das Einhalten des "Above the fold".

Um nun das Essverhalten = Ladeverhalten zu ändern, müssen wir dem Browser andere Essgewohnheiten aufzwängen und verändern das Timing, was wann geladen wird. Im Allgemeinen spricht man dabei vom "defer"-en, also dem hinten anstellen von dem, was weniger Priorität hat und begünstigen damit das"Above the fold" Ziel. Der Code Schnipsel übernimmt nun den Part was die Bilder anbetrifft, was im Grunde genommen wie folgt abläuft:

Beim Parsen der Seite geben wir dem Browser mit dem base 64 image ein Fake Bild. Das blockiert nicht beim Laden und der Browser bekommt, was er beim img Tag erwartet. Das data-src ignoriert er, weil er damit gemäß html Spezifikation nix anfangen kann. Anders als Du es annimmst, feuert die onload Anweisung erst, wenn alles HTML und andere Ressourcen geladen sind. Erst wenn alles geladen ist, wird auch die Funktion aus dem Schnipsel ausgeführt und diese Funktion macht im Grunde genommen nichts anders als das Fake Bild mit dem data-src zu ersetzen. Im generierten HTML Code, also nach Ausführen der Funktion steht dann auch das korrekte Bild im Source für das Bild.

Das für sich alleingestellt führt zu einem Besänftigung des Pagespeed Gottes, aber der will ja auch, dass das "Above the fold" Ziel eingehalten wird und dann soll auch noch der Nutzer bedient werden. Deswegen sollte man den Code Schnipsel nicht pauschal auf alle Bilder richten, sondern nur auf die Bilder nach dem Fold. Hat beispielsweise eine Seite im Above the fold ein Hauptbild und nach dem Fold noch weitere, bekommen nur die nach dem Fold stehenden Bilder das Fake Bild, bzw. den data-src Zusatz.

Ohne jetzt noch mehr zu zerreden, probiert es einfach aus und lasst mal den Pagespeed Test drüberlaufen. Erfolg ist garantiert. ;)

supervisior
PostRank 8
PostRank 8
Beiträge: 967
Registriert: 26.06.2006, 09:11

Beitrag von supervisior » 30.08.2018, 07:50

Vielleicht noch eine nicht unwichtige Anmerkung speziell zu diesem Thema und zum Optimieren im Allgemeinen. Man darf den hier beschriebenen Optimierungstipp nicht standalone betrachten. Durch das "Defer"-en von Inhalten, die weniger wichtig sind, reduziert sich unweigerlich die Zahl der gleichzeitigen Requests an den Server. Je nach Art des Servers und dessen verfügbare Performance kommt es zu einer Entlastung des Servers, eben weil er nicht mehr so viel gleichzeitig abarbeiten muss und das führt in Folge dessen zu der ebenso wichtigen Reduzierung der "Server Response Time, die der Pagespeed Gott ebenso gern gering hätte.

Man muss also nicht sofort auf einen leistungsstärkeren Server wechseln, sondern einfach nur mal die bekannten Methoden anwenden, wenngleich nicht alle so einfach umzusetzen sind, wie die hier beschriebene Methode.

Antworten
  • Vergleichbare Themen
    Antworten
    Zugriffe
    Letzter Beitrag