jQuery im Footer von WordPress laden — Die elegantere Variante

Seit WordPress 3.9 funktioniert diese Variante leider nicht mehr.

WordPress wird mit einigen JavaScript Bibliotheken ausgeliefert. Dazu gehören zum Beispiel script.aculo.us oder jQuery.
Plugins und Themes müssen diese Bibliotheken dann nicht mehr selbst mitausliefern, sondern können diese über die WP_Scripts API einbinden.

Direkt zur Lösung.

Registierung der Standardbibliotheken

Zuständig für die Registrierung der Standardbibliotheken ist die Funktion wp_default_scripts() in /wp-includes/script-loader.php. Ein Auszug:

<?php
/**
 * Register all WordPress scripts.
 *
 * @since 2.6.0
 *
 * @param object $scripts WP_Scripts object.
 */
function wp_default_scripts( &$scripts ) {
// &#91;…&#93;
	$scripts->add( 'colorpicker', "/wp-includes/js/colorpicker$suffix.js", array('prototype'), '3517m' );

	$scripts->add( 'editor', "/wp-admin/js/editor$suffix.js", array('utils','jquery'), false, 1 );
// […]
	// not used in core, replaced by Jcrop.js
	$scripts->add( 'cropper', '/wp-includes/js/crop/cropper.js', array('scriptaculous-dragdrop') );

	$scripts->add( 'jquery', '/wp-includes/js/jquery/jquery.js', array(), '1.7.2' );

	// full jQuery UI
	$scripts->add( 'jquery-ui-core', '/wp-includes/js/jquery/ui/jquery.ui.core.min.js', array('jquery'), '1.8.20', 1 );
	$scripts->add( 'jquery-effects-core', '/wp-includes/js/jquery/ui/jquery.effects.core.min.js', array('jquery'), '1.8.20', 1 );
// […]
}

WP_Dependencies->add() erwartet also die Argumente in der Reihenfolge Skriptname, Pfad zum Skript, Abhängigkeit zu anderen Skripten, Version des Skripts und zum Schluss das entscheidene Argument Einreihung in den Header oder Footer.

Nach dem selben Prinzip arbeiten übrigens auch wp_register_script() und wp_enqueue_script().

Warum JavaScript eigentlich in den Footer gehört

With scripts, progressive rendering is blocked for all content below the script. Moving scripts as low in the page as possible means there’s more content above the script that is rendered sooner.

The second problem caused by scripts is blocking parallel downloads.

Steve Souders in „High Performance Web Sites: Rule 6 – Move Scripts to the Bottom

Zusammengefasst: Erkennt der Browser ein Skript, wird das Skript zunächst abgearbeitet und alles andere muss warten.

jQuery für den Footer registrieren

Schaut man sich nun nochmal obige markierte Zeile an, so erkennt man schnell, dass der letzte Parameter bei der jQuery Registrierung nicht gesetzt wurde.
Daraus folgt, dass, wenn jQuery eingebunden wird, die Skripteinbindung automatisch in den Header gelegt wird.

Gerade für Theme-Entwickler und im Bezug auf die Performance einer Seite ist dies sehr ungünstig. Wird ein zusätzliches Skript mit jQuery Abhängigkeit in den Footer eingebunden, bleibt jQuery weiterhin im Header.

Um jQuery trotzdem in den Footer zu bekommen, wird im Netz recht häufig die Variante über wp_deregister_script( 'jquery' ) angepriesen. — Erst die originale Skriptdefinition löschen und dann wieder mit dem letzten Parameter neu definieren. Sehr unflexibel, da für die Neuregistrierung die jQuery Version und der Pfad zur Datei gebraucht wird.

Aus diesem Grund möchte ich nun auf die elegantere Variante eingehen.

PHP / RAW / github:gist
<?php
/**
 * Prints jQuery in footer on front-end.
 */
function ds_print_jquery_in_footer( &$scripts) {
	if ( ! is_admin() )
		$scripts->add_data( 'jquery', 'group', 1 );
}
add_action( 'wp_default_scripts', 'ds_print_jquery_in_footer' );

Bei dieser Methode klinkt man sich in den wp_default_scripts Hook ein. Dieser übergibt als Parameter ein Objekt vom Typ WP_Scripts, wo unter anderem die registrierten Skripte enthalten sind.
Die Definitionen zu jQuery sind daher in $scripts->registered['jquery'] deklariert:

[jquery] => _WP_Dependency Object
	(
		[handle] => jquery
		[src] => /wp-includes/js/jquery/jquery.js
		[deps] => Array
 			(
			)
 		[ver] => 1.7.2
		[args] => 
		[extra] => Array
			(
			)
	)

Damit WordPress jQuery nun im Footer einbindet, muss das Feld extra um dem Wert group => 1 ergänzt werden.
Dazu steht die Methode WP_Dependencies->add_data( $handle, $key, $value ) zur Verfügung.

Zusammengefasst ergibt sich schlussendlich $scripts->add_data( 'jquery', 'group', 1 );.

Wer eine PHP Version größer 5.3 einsetzt kann übrigens auch auf eine anonyme Funktion setzen:

PHP / RAW / github:gist
<?php
/**
 * Prints jQuery in footer on front-end.
 * For PHP > 5.3
 */
add_action(
	'wp_default_scripts',
	function( &$scripts ) {
		if ( ! is_admin() )
			$scripts->add_data( 'jquery', 'group', 1 );
	}
);

Zum Thema

7 thoughts on “jQuery im Footer von WordPress laden — Die elegantere Variante”

  1. Was ich wirklich nicht verstehe.. wenn dieses Vorgehen doch von allen als bester Weg angesehen wird, warum verschiebt WordPress das Laden nicht in den Release-Versionen in den Footer?

    1. Hi Thomas,
      berechtigte Frage. Das Problem liegt darin, dass es noch Themes bzw. Plugins gibt, welche ihre Zeilen JavaScript inline einbinden. Und dann noch direkt im wp_head Hook.
      Dadurch, dass jQuery nun im Footer geladen wird, wäre dies zu spät für das inline Skript. Folge: Es hagelt JavaScript-Fehler.

      Hat man aber einen Überblick über seine eingesetzte Themes und Plugins und weiß, dass diese auf die offizielle API setzen, kann die obige Methode (oder jede andere auch) erst genutzt werden.

    2. So ganz trivial ist die Antwort vielleicht doch nicht. Ginge es lediglich um schlecht programmierte Themes und Plugins, würde ich den WP-Entwicklern zutrauen das sie auf diese Themes &Plugins pfeifen und jQuery einfach im Footer laden. Es wäre meiner Meinung nach auch die richtige Entscheidung.
      Googelt man jedoch mal danach ob es besser ist jQuery im Head oder im Footer zu laden, dann stößt man schnell auf Berichte das es vor allem im Zusammenhang mit jQuery UI und einigen jQuery-Plugins zu Problemen kommen kann. Ich gehe mal davon aus das dies der Grund ist warum jQuery die einzige Bibliothek ist die WordPress per Default in den Head lädt.

      Sam Saffron beschreibt in einem Blogartikel (http://samsaffron.com/archive/2012/02/17/stop-paying-your-jquery-tax/) warum es ganz sinnvoll sein kann jQuery im Footer zu laden. Am Ende des Artikels beschreibt er auch einen Workaround wie man damit umgeht wenn jQuery im Head oder inline genutzt wird (in den Kommentaren sind noch einige verbesserte Lösungen).

  2. was kann alles schief gelaufen sein, wenn das Script sich hartnäckigst weigert in den footer zu wandern?

    egal, ob ich deine elegante oder die weniger elegante nehm, es bleibt oben :(

    bin akut wohl zu blind

    1. Dann liegt es daran, dass es ein Skript gibt, welches jQuery benötigt, aber selbst für den Header registriert ist. WordPress erkennt dies und lädt jQuery dann im Header.

      Lokal ist das bei mir zB mit der Debug Bar auch der Fall.

  3. das bedeutet, ich soll es dann so lassen ?

    oder einfach guggen was alle nicht funktioniert, wenn ich einfach alle Scripte aus wp_head nehme und das “hart ” im footer verlinke

  4. Hi,
    tut mir echt leid, aber ich begreif es nicht wirklich was bzw. wie Du das erklärt hast.
    Bin mir WordPress absoluter Neuling und versuch mich da gerade.
    Könntest Du mir das bitte so erklären das es auch ein Dummer versteht. Vielen Dank im voraus.
    LG Dieter

Leave a Reply