Defer JavaScript für schnelleres Laden

JavaScript blockiert den Ladevorgang

Wenn der Browser-HTML-Parser zu einem SCRIPT-Tag mit SRC-Attribut gelangt, wird die entsprechende JavaScript-Datei heruntergeladen und der darin enthaltene Code sofort ausgeführt. Inhalte die nach dem SCRIPT-Tag stehen werden erst geparsed, nach dem das JavaScript ausgeführt wurde. Abhängig von Dateigrösse und Komplexität der JavaScript-Datei, kann der Parse-Prozess des Browsers und die Ladezeit der Website zum Teil massiv beeinträchtigt werden. Das führt zu einer unnötig langen Wartezeit für den Benutzer und einer schlechteren Position im Suchresultat von Suchmaschinen wie Goolge. Die Wartezeit kann verkürzt werden in dem das JavaScript, oder zumindest ein Teil davon zeitlich verschoben (engl. defer) geladen und ausgeführt wird. Dieser Vorschlag stammt von Google und ist als Best Practice unter den PageSpeed-Regeln dokumentiert.

Drei Ladezeitpunkte

Die drei Zeitpunkte, bei denen JavaScript-Sourcen geladen und ausgeführt werden können sind:

DOMContentLoaded ist der Zeitpunkt, bei dem der HTML-Markup vollständig heruntergeladen und geparsed wurde ohne den Ladevorgang Ressourcen wie Bilder zu berücksichtigen. Das DOM ist ab diesem Zeitpunkt bereit für Anpassungen  durch JavaScript. In bestimmten Fällen macht es Sinn JavaScript schon vor diesem Event auszuführen, z.B. um Daten von einem Dritt-Server möglichst früh abzurufen. Solche Fälle sind eher eine Ausnahme und lassen sich auch anders lösen. Load ist Zeitpunkt, bei dem eine Website inklusive eingebundene Ressourcen (Bilder, Stylesheets, JavaScript, iFrames) vollständig geladen ist. Dieser Event findet in jedem Fall nach DOMContentLoaded statt.

jQuery Document Ready und Window Load

jQuery ist mittlerweile zur defacto Frontend-Bilbliothek geworden und wird in die Mehrheit der Web-Projekt eingebunden.  jQuery bietet eine Abstraktion vom DOMContentLoaded-Event an. Dieser DOM-Ready-Event lässt sich wie folgt nutzen (siehe auch):

$(document).ready(function () {
    alert('DOM ist bereit!');
});

Um den späteren Load-Zeitpunkt zu ermitteln eignet sich folgender Aufruf (siehe auch):

$(window).load(function () {
    alert('DOM ist bereit und sämtliche Inhalte wurden geladen');
});

 

In den PageSpeed-Regeln schlägt Google vor die weniger wichtigen JavaScripts beim Load-Event zu laden anstatt alles beim DOM-Ready.

Google’s Defer

Google schlägt vor den Load-Event zu nutzen um sekundäre JavaScript-Sourcen in die Website einzubinden. Nicht alle JavaScripts müssen schon beim DOM-Ready geladen sein und ausgeführt werden. Es gibt wichtige JavaScripts (primär), z.B. Funktionalität für die Hauptnavigation und weniger wichtige (sekundäre) JavaScripts, z.B. Social-Buttons und Kommentarfunktionen. Primäre JavaScripts werden beim DOM-Ready-Event geladen. Sekundäre JavaScripts beim Load-Event. Was sich bis zum Load-Event verschieben lässt, sollte auch bis zu diesem Zeitpunkt verzögert werden. Das Code-Snippsel (Quelle) von Google sieht wie folgt aus:

<script type="text/javascript">
 // 1. Add a script element as a child of the body
 function downloadJSAtOnload() {
     var element = document.createElement("script");
     element.src = "deferredfunctions.js";
     document.body.appendChild(element);
 }
 // 2. Check for browser support of event handling capability
 if (window.addEventListener)
     window.addEventListener("load", downloadJSAtOnload, false);
 else if (window.attachEvent)
     window.attachEvent("onload", downloadJSAtOnload);
 else window.onload = downloadJSAtOnload;
</script>

 

Die Lösung von Google ist mit reinem JavaScript geschrieben. Mit einer Library wie jQuery im Einsatz kann der zweite Block wie folgt gekürzt werden:

$(window).load(downloadJSAtOnload);

Da die Funktion downloadJSAtOnload nichts anderes macht, als einen SCRIPT-Tag in den HEAD-Tag zu schreiben um die JavaScript-Datei deferredfunctions.js einzubinden, kann auch diese Funktion durch die Nutzung von jQuery weggekürzt werden: $(window).load(function () { $.getScript(‚js/longloadingscript.js‘); }); Konkretes Beispiel mit jQuery Im Idealfall lädt man die primären JavaScripts beim Dom-Ready-Event und die sekundären, weniger wichtigen, beim Window-Load-Event. JavaScripts sollten grundsätzlich so spät wie möglich und erst wenn nötig geladen werden.

<html>
    <head>
    …
    </head>
    <body>
    …
    …
    …
    <script src="jquery.js"></script>
    <script src="MyAPP.js"></script>
    <script>
        $(document).ready(function () {
            // initialize primary javascripts
            MyAPP.Init();
        });
        $(window).load(function () {
            // initialize secondary javascripts
            // Social buttons, weather widget, fancy animation near footer
            $.getScript('js/MyAPP.Social.js');
        });
    </script>
    <body>
</html>

In diesem Beispiel könnte man das MyApp.js auch im DOM-Ready-Block laden. Man sollte jedoch nicht zu früh optimieren oder die Performance zu lasten der Wartbarkeit und Übersicht steigern.

$(document).ready(function () {
    // initialize primary javascripts
    $.getScript('js/MyApp.js', function () {
        MyAPP.Init();
    });
});

 

Fazit

Die Initialladezeit einer Website kann mit der Defer-Methode, wie Google sie vorschlägt, deutlich verbessert werden. Es ist nicht notwendig alles an JavaScript beim DOM-Ready-Event zu laden. Funktionen für Social-Buttons und AJAX-Abrufe (Sekundär) können durchaus von inhaltlich kritischen Funktionen (Primär) wie Beispielsweise Funktionen für die Hauptnavigation oder Seitendarstellung getrennt werden. Die Aufteilung erlaubt das Laden von Primär-JavaScript beim DOM-Ready-Event und Sekundär-JavaScript beim Load-Event. Die schnellere Ladezeit wirkt sich positiv auf den Benutzer und dem Google Page Ranking aus. Referenzen:

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>