Blog zu den Themen Webentwicklung, technisches Online Marketing und Suchmaschinenoptimierung

Ladezeit: Facebook Like-Button per jQuery nachladen

Vor wenigen Tagen flog ein Tweet von Herrn Kratz (@karlkratz) durch meine Twitter-Timeline, in dem es hieß: „Der Facbook #like Button ist PageSpeed-technisch eine echte Wutz. :-(„.

Diese Aussage konnte ich auf Grund meiner eigenen gemachten Erfahrungen nur bestätigen. Obwohl sich die Ladezeiten mit der neuen fbml-Methode gegenüber der alten iframe-Methode schon gebessert haben, wird dem Benutzer weiterhin suggeriert, die Webseite befindet sich in einem Ladezustand.

Zum Beispiel verhaart der Cursor so lange im Ladezustand und auch in Browsern mit Fußleiste (z.B. Firefox) erkennt der erfahrene Benutzer, dass sich die Seite noch beim Laden befindet. Objektiv ist dies natürlich nicht der Fall, da sich die Webseite meist schon vollständig bedienen lässt. Jedoch darf man das subjektive Empfinden des Besuchers gegenüber Ladezeiten auch nicht unterschätzen.

Schauen wir uns zuerst einen Quelltextauszug an, wie man den Facebook Like-Button normalerweise integriert.

Like-Button erst laden, wenn Seite komplett

Diesem Zustand kann man jedoch mit etwas Quellcode bequem entgegen wirken. Meine Zielsetzung: Den Button erst anzeigen, wenn wirklich alle Seitenelemente (HTML, CSS, Bilder, usw) vollständig geladen sind.

In diesem Artikel (wie auch in fast allen anderen Javascript-lastigen Beiträgen) verwende ich das jQuery-Framework. jQuery wird von WordPress bereits standardmäßig mitgeliefert und ist in den meisten kostenfreien sowie kostenpflichtigen Themes integriert. Alle die nicht mit WordPress arbeiten, können jQuery bequem über die Google-Server einbinden:

Damit wäre der Grundstein für unser kleines Projekt gelegt. Nun entfernen wir den Like-Button aus unserem Quellcode, lassen jedoch den div-Container mit der ID weiter bestehen. Dies ist nötig, um später einen „Ansprechpartner“ zu haben, in den wir den Facebook Like-Button wieder einfügen können.

Zeit für AJAX

Nun ist es Zeit Javascript beziehungsweise jQuery ins Spiel zu bringen. Den folgenden Quellcode könnt ihr entweder direkt in den head-Bereich eurer Seite innerhalb eines <script></script> einfügen oder ihr wählt die saubere Variante und lagert das Javascript in eine externe Datei aus.

Natürlich möchte ich euch den Quellcode wie gewohnt erläutern:

  • Zeile 1: Wir nutzen die ready-Funktion von jQuery. Diese wird aktiviert, wenn alle Elemente des DOM zur Verfügung stehen und man auf sie zugreifen kann.
  • Zeile 2: Dem Objekt window weisen wir das jQuery load-Event zu. Das bedeutet, die Callback-Funktion wird erst ausgeführt, wenn wirklich alle Seitenelemente vollständig geladen sind.
  • Zeile 3: In der Callback-Funktion starten wir einen jQuery-AJAX-Request mit Hilfe der Methode $.get(). Dazu rufen wir die Datei ajax.php auf, welche in diesem Beispiel im selben Verzeichnis wie unsere Quelldatei liegen muss. Parameter übergeben wir erst einmal keine, da in der ajax.php nur eine Rückgabe stattfinden wird. In der Callback-Funktion der $.get()-Methode erhalten wir die data-Variable, welche unseren Rückgabe-String enthält.
  • Zeile 4: Den data-String geben wir im div-Container mit der ID „#likebutton“ aus.

Obwohl ihr euch denken könnt, was in der Datei ajax.php steht, hier noch der Vollständigkeit halber der entsprechende Quellcode:

Update: AJAX-Request mit nativem Javascript

Wie in den Kommentaren ersichtlich, macht es manchmal wenig Sinn, auf Webseiten ohne jQuery extra dieses Framework zu implementieren, nur um die Ladezeit zu schonen. Der positive Effekt wäre durch die Einbindung der großen Javascript-Bibliothek wieder aufgehoben.

Deshalb im folgenden ein AJAX-Request, der ohne jQuery auskommt. Bitte beachtet jedoch, dass ihr den body-Tag wie folgt abändern müsst, um die entsprechende Funktion ohne die $.ready()-Methode zu öffnen:

Nun der neue native Javascript-Quellcode:

An dieser Stelle verzichte ich jedoch auf eine Erläuterung jeder Zeile. Wenn Fragen auftauchen, können diese sehr gerne per Kommentar gestellt werden.

Interessant finde ich auf jeden Fall auch die Gegenüberstellung der nativen Javascript- mit der jQuery-Variante. Ich liebe dieses Framework! ;-)

Dieser Artikel wurde am 19.02.2011 veröffentlicht

Wer schreibt hier?

Torben Leuschner - Webentwickler

Hi, ich bin Torben und baue leidenschaftlich gerne Webseiten. Also habe ich mein Hobby zum Beruf gemacht und bin seit 2008 als Webentwickler Selbständig tätig. Obwohl ich schwerpunktmäßig für Kunden arbeite habe ich auch sehr viel Freude an der Realisierung eigener Projekte. Daraus resultierend hat sich eine große Affinität zu den Themen Online Marketing und Suchmaschinenoptimierung entwickelt. Gelegentlich schreibe ich auf Twitter, viel aktiver bin ich allerdings auf Facebook. Gerne können wir uns dort vernetzen!

Wie stehst du dazu?

  1. Hallo Torben,

    ich finde es Klasse, dass Du der Mikro-Diskussion auf Twitter so engagiert nachgehst und einen sehr guten technischen Artikel dafür erstellt hast. Ich bin mir sicher, dass dieser vielen Menschen wertvolle Dienste leisten wird :-)

    Jetzt nochmal der Spezialfall einer Single Landing Page mit Maniker-Anspruch an die Ladezeit (nicht die Ladegeschwindigkeit): Ich werde mich hüten, in einer jQuery-freie Landingpage mit 5 kb Größe noch jQuery nachzuladen ;-) Vom zusätzlichen HTTP-Request abgesehen (auch wenn dieser von einer parallel ladbaren Quelle, sogar aus einem CDN stammt) wartet die Suchmaschine der Landing Page Besucher dann auch noch, bis jQuery geladen ist – das nimmt vielen Seiten den „crispen“, ultraschnellen Aufbau.

    Für Single Landing Pages, die ohnehin andere jQuery-Komponenten integriert haben (z.B. für SEO- oder Designzwecke) ist Deine Lösung natürlich genial :-)

    Viele Grüße,

    Karl

  2. Hallo Karl,

    damit triffst du natürlich ins Blaue. Eventuell war ich etwas voreilig, da jQuery bei mir mittlerweile zur Standardausrüstung jedes Webprojektes gehört.

    Natürlich müssen die, ich glaube, momentan 23kb auch erst geladen werden und der Effekt ist auf Seiten ohne jQuery für die Katz.

    Eventuell schieb ich noch ein Update hinterher, wie es auch ohne jQuery funktioniert!

  3. Moin Torben,

    dann werd ich mir die Tage mal die Zeit nehmen und den Like-Button mal wieder reaktivieren und schauen wie viel Ladezeit sich mit der jQuery-Methode einsparen lässt.

    Grüße
    Lars

  4. Gute Idee, habe ich gleich bei mir eingebaut. Aber warum der Umweg über die ajax.php? Kann man doch auch gleich so einbinden:

    $(function(){
    $(window).bind(„load“, function(){
    $(„#sidebarfacebook“).html(“);
    });
    })

    Oder wenn man die iFrame-Variante nutzt, so (Beispiel von andiministrator.de):

    $(function(){
    $(window).bind(„load“, function(){
    $(„#sidebarfacebook“).html(“);
    });
    })

  5. Hallo Andi,

    da hast du natürlich Recht mit. Ich wollte das Tutorial nur möglichst schlank halten, damit auch Nicht-Javascriptler es verstehen. Bei deiner Methode muss man eben doch drauf achten, dass die Anführungsstriche richtig formatiert sind.

    Nichtsdestotrotz ist deine Lösung für Profis natürlich absolut korrekt – vielen Dank auch für den Verweis auf deiner Webseite :)

  6. Mir ist auch das in letzter Zeit, immer häufiger längere Warten auf Facebook aufgefallen. Um die Share-Buttons selber zu gestalten, aber trotzdem zu wissen, wie viele Shares eine Seite hat, bin ich noch ein Schritt weiter gegangen und lade auch keine iFrames nachträglich.

    Wer Lust hat kann sich das ja mal unter
    http://auit.de/code-snippets/magento-social-bookmark-extension-tab-und-toolbar-update-23-02-2011-85-article

    anschauen.
    Ist zwar eine Extension für Magento, kann aber auch für andere Aufgaben verwendet werden.

  7. Hallo Torben,

    wenn ich das richig sehe, funktioniert das Ganze in WordPress aber nur, wenn ich innerhalb des Skripts keine Template-Tags verwende. Wenn ich (wie auf matthiaspabst.de) auf der Index-Seite unter jedem Artikel den Like-Button einbinden will, muss ich mir ja mit dem Template Tag the_permalink den Permalink des jeweiligen Artikels holen. Und da scheint diese Methode zu scheitern. Selbst wenn ich das Skript direkt vor dem zu befüllenden Container einbinde und es somit innerhalb des Loops ist, zeigt es für alle Artikel den Permalink vom ersten Artikel an. Vermutlich, weil der Permalink erst ermittelt wird, nachdem die Loops für die Artikel schon durchlaufen wurden.
    Schade. Gerade wenn ich den Like-Button 10x aufrufe, wäre der Geschwindigkeitsvorteil wünschenswert. Oder gibt’s da einen anderen Lösungsweg?

    Gruß
    Matthias

  8. Hey Matthias,

    es gibt immer einen anderen Lösungsweg ;-)

    Zu deinem Problem:
    1.) Beim Like-Button muss doch gar keine URL mitgegeben werden? Wenn du das Feld leer lässt, zieht sich das Script immer automatisch die Seite, auf dem sich der Nutzer gerade befindet. Eine URL macht nur Sinn, wenn man eine FB-Gruppe oder eine bestimmte Seite „liken“ will.
    // Edit: Sorry, du redest von einer Index-Seite, ok, kommen wir zu Punkt 2.

    2.) Möchtest du mehrere Like-Buttons mit unterschiedlichen Ziel-URLs verwenden, muss das Javascript ausgebaut werden. Du könntest z.B. in der Schleife jedesmal ein script-Tag aufrufen und darein einen JS-Array per PHP-Permalink befüllen. Am Ende gehst du dann mit einer jQuery each-Schleife alle Felder durch und übergibst dem AJAX-Request als Parameter den entsprechenden Array-Inhalt. Lösbar ist es auf jeden Fall.

  9. Hi Torben,

    1.) Genau, es ist ja für jeden Artikel eine andere URL.
    2.) So was in der Richtung schwebt mir auch vor. Werde mal tüfteln und darüber berichten, falls erfolgreich.

  10. Es ist eigentlich recht easy. Wenn du möchtest, kannst du dich ja mal bei mir im Skype melden, dann schick ich dir den Quellcode kurz rüber ;-)

  11. Kann es sein, dass deine Like-Box nicht funktioniert? Ich werde durch Klicken jedenfalls nicht zum Fan (bei FB direkt aber schon).

    Werd deine Lösung jetzt gleich mal ausprobieren. Hab den Tipp von KK auf der Campixx bekommen, vielen Dank dafür :-)

  12. Guten Morgen !

    Müsste es nicht korrekterweise ActiveXObject(„Microsoft.XMLHTTP“) heissen ?! Ich bilde mir ein, daß sonst IE6 Nutzer Probleme haben und ein kleines gelbes Rufzeichen den Javascript Fehler anzeigt.

  13. Hehe dass kann ich dir so gar nicht sagen. Für den IE6 optimiere ich seit Anfang 2010 nicht mehr und sage auch Kunden im Voraus, dass eine Optimierung dafür von meiner Seite aus nicht mehr drin ist.

  14. Hm, habe das nach Methode 2 eingebaut da ich kein jquery verwende.
    Funktioniert leider nicht :-(

    Habe diese Dinge eingebaut (hier kopiert)
    DIV mit id Likebutton
    BODY onload funktion
    Javascripts die auch ausgeführt werden bis document.getElementById(‚likebutton‘).innerHTML = data;
    und das ajax.php mit dem facebook code.

    Nur es erscheint kein Facebook button :-(

  15. Achso, das ajax.php wird auch ausgeführt. Wenn ich nur eine HELLO Ausgabe mache dann erscheint diese. Aber der FB Button erscheint nicht im div. Hat wer eine Idee?

  16. Also ich habs auch satt, nutze die HTML5 Variante des FB Button aber bei mir läd er direkt nach, hab die Scripte in den footer verschoben, trotzdem viel zu lange bis die Seite ready ist, auch andere externe Scripte wie Adsense sind performance lastig.

    Wie schafft man es in der heutigen Zeit eine Seite in weniger als 1 Sekunden laden zu lassen?

  17. Hallo Norbert!

    Ich empfehle dir den FB Button so einzubinden wie im Script oben und zusätzlich rufst du die function() nicht sofort auf sondern z.b. erst nach 10 Sekunden. Damit zähl es niemals irgendwie zum Seitenaufbau und die Besucher suchen ja auch nicht in den ersten 10 Sekunden nach dem Button. Es ist glaube ich sogar so, dass die Aufmerksamkeit auf den FB eher noch erhöht wird wenn er erst nach 10 oder 15 Sekunden plötzlich erscheint. (Wenn man das überhaupt möchte…)

  18. Wie kann ich mittels der Ajax Variante weitere Module nachladen lassen?

    Also z.B.
    1x Facebook Like Box
    1x Google Plus

    Danke

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

* Die Checkbox für die Zustimmung zur Speicherung ist nach DSGVO zwingend.

Ich stimme zu.