Lizenz des Textes: CC BY-SA 3.0
CC-BY-SA-Logo

CSS und Javascript nur bei Bedarf auf WordPress-Seiten einfügen

Teilen

Webseiten, die mit WordPress erstellt wurden, enthalten oft CSS, Javascript und anderen Code, der auf vielen Seiten nicht benötigt wird. In diesem Beitrag werden zwei Möglichkeiten erklärt, wie man diesen Code vollständig oder aus bestimmten Seiten entfernt. Am Ende erläutere ich, wie in meinem WordPress-Theme nur der Code einfügt wird, der auf der entsprechenden Seite auch benötigt wird.

Laptop mit PHP Code in Nahaufnahme

Einführung und Motivation

Auf den Seiten meines Blogs haben sich CSS, Javascript und anderer Code befunden, die für diese Seiten nicht benötigt wurden. Dieser zusätzliche Code muss an den Browser übertragen und ausgewertet werden, was zu einer längeren Ladezeit führt und somit die Core Web Vitals negativ beeinflusst.

Mein Blog benutzt als Backend WordPress. WordPress bringt mit Gutenberg eine grafische Benutzeroberfläche zum Gestalten von Webseiten mit. Diese Benutzeroberfläche benötigt CSS und weiteren Code, damit sie ordnungsgemäß funktioniert. Manche dieser Codes werden standardmäßig auf der Webseite eingebunden, obwohl diese dort meist nicht benötigt werden. Eines dieser Stylesheets sind die Global Styles, die z. B. folgendermaßen im Header der Seite eingebunden werden und für den eigentlichen Betrieb meiner Webseite nicht benötigt werden (WordPress Version 5.9.3):

<style id='global-styles-inline-css'>
...
</style>

Eine andere Quelle von nicht benötigten Code auf der Webseite sind Plugins. Für mein Kontaktformular verwende ich das Plugin Contact Form 7. In der Version 5.5.6 von Contact Form 7 werden neben der styles.css auch die Bibliotheken regenerator-runtime.js und wp-polyfill.js eingebunden. Die für das Kontaktformular benötigten Stylesheets und Codes werden allerdings auf jeder Seite eingebunden, obwohl sie nur beim Kontaktformular selbst benötigt werden.

Für eine Webseite wäre es optimal, diese Stylessheets und Codes nur auf den Seiten einzufügen, auf denen sie auch gebraucht werden.

CSS und anderen Code mit wp_dequeue_style und wp_dequeue_script entfernen

In WordPress werden Stylesheets mit den Funktionen wp_enqueue_style und wp_add_inline_style eingebunden. Javascript und anderer Code wird mit den Funktionen wp_enqueue_script und wp_add_inline_script eingebunden.

Um nicht benötigte Stylesheets und anderen Code zu entfernen, kann man die Funktionen wp_dequeue_style und wp_dequeue_script verwenden.

Da WordPress mit Hooks arbeitet, um in den Programmablauf einzugreifen, müssen die Funktionen wp_dequeue_style und wp_dequeue_script im richtigen Hook aufgerufen werden. Der Hook wp_print_styles wird aufgerufen, unmittelbar, bevor die Stylesheets auf der Seite ausgegeben werden. Zu diesem Zeitpunkt wurde in der Regel auch noch kein Javascript ausgegeben. Die Funktionen wp_dequeue_style und wp_dequeue_script sollten also in diesem Hook aufgerufen werden.

Um dafür zu sorgen, dass die oben beschriebenen Global Styles nicht auf der Seite ausgegeben werden, reicht es aus, die Funktion wp_dequeue_style im Hook wp_print_styles auszuführen. Der entsprechende Code in der functions.php sieht demnach folgendermaßen aus:

add_action( 'wp_print_styles', 'tk_deregister_styles', 100 );
function tk_deregister_styles() {
    wp_dequeue_style( 'global-styles' );
}

Es kommt allerdings auch vor, dass man Stylesheets und anderen Code nur auf bestimmten Seiten einbinden oder ausschließen möchte. Möchte man unter anderem die Global Styles nur dann ausschließen, wenn man sich nicht in der Administrator-Oberfläche befindet, dann kann man den obigen Codeausschnitt folgendermaßen erweitern:

add_action( 'wp_print_styles', 'tk_deregister_styles', 100 );
function tk_deregister_styles() {
    if( !is_admin() ){
        wp_dequeue_style( 'global-styles' );
    }
}

Es ist nicht immer möglich, Stylessheets und anderen Code mit den Funktionen wp_dequeue_style und wp_dequeue_script zu entfernen. Dies hängt davon ab, wie das Plugin oder das Theme programmiert worden ist und ob der Code mit den Funktionen wp_enqueue_style, wp_register_script, wp_add_inline_style oder wp_add_inline_script eingebunden wurde.

WordPress-Plugins auf bestimmten Seiten deaktivieren

Neben der im vorigen Abschnitt beschriebenen Methode, mit den Funktionen wp_dequeue_style und wp_dequeue_script, kann man auch einzelne Plugins auf bestimmten Seiten aktivieren oder deaktivieren. Dies macht besonders dann Sinn, wenn ein Plugin nicht nur ein einzelnes Stylesheet auf den Seiten einbindet, sondern mehrere Codeabschnitte. Außerdem kann bei einem Update des Plugins die Art und Weise wie der Code eingebunden wird sich ändern, sodass dann gegebenenfalls die functions.php angepasst werden muss. In diesen Fällen ist es besser dafür zu sorgen, dass WordPress das Plugin nur auf bestimmten Seiten aktiviert und auf den anderen deaktiviert.

Wie im ersten Abschnitt beschrieben, benutze ich für das Kontaktformular auf diesem Blog das Plugin Contact Form 7. Ich habe meine WordPress-Installation so angepasst, dass dieses Plugin nur aktiviert wird, wenn das Kontaktformular aufgerufen wird.

Wie genau man WordPress-Plugins auf bestimmten Seiten aktiviert und deaktiviert, ist in einem Blogbeitrag von Kinsta sehr ausführlich beschrieben:

→ Wie man das Laden von WordPress-Plugins auf bestimmten Seiten und Beiträgen deaktiviert

In meinem WordPress-Theme und in diesem Beitrag habe ich mich im Wesentlichen an die programmiergestützte Methode aus dem Blogbeitrag von Kinsta gehalten. Die dort beschriebene Methode ist eine schöne und elegante Lösung für das Aktivieren und Deaktivieren von WordPress-Plugins auf bestimmten Seiten.

Das Aktivieren oder Deaktivieren von Plugins auf bestimmten Seiten ist in WordPress nur über Must Use Plugins (mu-plugins) möglich. Must Use Plugins sind spezielle Plugins, die automatisch auf allen Seiten der WordPress-Installation aktiviert sind. Diese Plugins werden nicht auf der Standardseite der Plugins angezeigt. Um ein Must Use Plugin zu erstellen, reicht es aus, eine php-Datei im Ordner wp-content/mu-plugins anzulegen. Falls der Ordner mu-plugins noch nicht existiert, muss dieser angelegt werden.

In einem Must Use Plugin steht der Hook option_active_plugins zur Verfügung, mit dem man selektiv Plugins aktivieren und deaktivieren kann. In meiner WordPress-Installation habe ich die Datei wp-content/mu-plugins/tk-mu-plugins.php angelegt, in der der Code für das Must Use Plugin enthalten ist.

Am Anfang eines Plugin steht immer der Header, wo allgemeine Angaben zu diesem Plugin stehen. Der Header muss mindestens den Eintrag Plugin Name: enthalten, damit WordPress die Datei als Plugin erkennt. In meinem Plugin sieht der Header folgendermaßen aus:

<?php
/*
Plugin Name: TK-MU-Plugin
Description: 
Author: Thomas Krakow
Version: 1.0
Author URI: https://thomas-krakow.de
*/

Über die URL, mit der unsere Seite aufgerufen wurde, stellen wir fest auf welcher Seite wir uns befinden. Wir wollen den Hook option_active_plugins nur dann aufrufen, wenn wir uns nicht in der Administrationsoberfläche befinden. Dies können wir feststellen, indem wir überprüfen, ob die Zeichenkette /wp-admin/ in der URL vorkommt, mit der diese Seite aufgerufen wurde.

$fRequestURI = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
if( false === strpos( $fRequestURI, '/wp-admin/' ) ){		    
    add_filter( 'option_active_plugins', 'tk_activate_plugins' );
}

Die URL wird ebenfalls dazu benutzt, um in der Funktion tk_activate_plugins abzufragen, ob das Kontaktformular aufgerufen werden soll.

global $fRequestURI;
$is_contact_page = strpos( $fRequestURI, '/kontakt/' );

Anschließend wird in der Liste der Plugins ($plugins) nach dem Plugin Contact Form 7 gesucht und deaktiviert, wenn nicht das Kontaktformular aufgerufen werden soll.

$k = array_search( "contact-form-7/wp-contact-form-7.php", $plugins );
    
if( false !== $k && false === $is_contact_page ){
    unset( $plugins[$k] );
}

Das Plugin Contact Form 7 verwendet zum Senden von Nachrichten, die WordPress REST-API . Hierbei wird beim Versenden der Nachricht ein JSON-Datensatz mittels JavaScript an WordPress gesendet. Dazu definiert das Plugin Contact Form 7 einen Endpunkt, der eine nichts anderes als spezielle URL ist. Der Endpunkt für Contact Form 7 auf meinem Blog sieht beispielsweise folgendermaßen aus:

https://thomas-krakow.de/wp-json/contact-form-7/v1/contact-forms/698/feedback

Was auffällt, ist, dass die Zeichenkette '/kontakt/' aus der URL, welche wir oben noch als Kriterium verwendet haben, nicht in diesem Endpunkt (URL) vorkommt. Wenn ein Anwender demnach eine Nachricht versenden möchte und damit die URL aufrufen würde, würde WordPress das Plugin nicht aktivieren. Diese Endpunkte müssten allerdings mit register_rest_route registriert werden, welches direkt in Contact Form 7 erfolgt. Da das Plugin beim Aufruf dieser URL allerdings nicht aktiviert wird, existiert dieser Endpunkt (URL) auch nicht, weshalb sich keine Nachrichten mehr über Contact Form 7 versenden lassen. Der Browser würde in seiner Konsole die Meldung ausgeben, dass die URL

https://thomas-krakow.de/wp-json/contact-form-7/v1/contact-forms/698/feedback

nicht erreichbar ist und den HTTP-Statuscode 404 ausgeben.

Um das Plugin auch beim Aufruf der REST-API zu aktivieren, müssen wir ein zweites Kriterium hinzufügen. Wir aktivieren, das Plugin auch dann, wenn in der URL die Zeichenkette '/contact-forms/' enthalten ist. Unser Codeausschnitt sieht demnach folgendermaßen aus:

$is_contact_page = strpos( $fRequestURI, '/kontakt/' );
$is_rest_api = strpos( $fRequestURI, '/contact-forms/' );
    
$k = array_search( "contact-form-7/wp-contact-form-7.php", $plugins );
    
if( false !== $k && false === $is_contact_page && false === $is_rest_api ){
    unset( $plugins[$k] );
}

Am Ende der Funktion muss dann nur noch die Liste der Plugins zurückgegeben werden:

return $plugins;

Den vollständigen Code für dieses Must Use Plugin habe ich auf GitHub Gist zur Verfügung gestellt:

→ tk-mu-plugins.php

Stylesheets und Javascript-Code nur dann einbinden, wenn sie benötigt werden

Der Königsweg ist, wenn auf einer Seite nur der Code eingebunden wird, der auch wirklich zur Darstellung der Seite benötigt wird. Hierzu möchte ich einmal die Idee vorstellen, die ich in meinem WordPress-Theme verwendet habe.

Zuerst habe ich alle nicht benötigten Stylesheets und andere Codes mit den beiden oben beschriebenen Methoden entfernt. Damit mein Theme erkennt, welchen zusätzlichen Code er auf der Seite einfügen muss, habe ich alle Funktionalitäten in Shortcodes hinterlegt. Beim Aufruf einer Seite wird jeder Shortcode zweimal durchlaufen. Beim ersten Durchlauf teilt der Shortcode mit, welche Stylesheets und andere Codes WordPress auf der Seite einfügen soll. Im zweiten Durchlauf rendert der Shortcode den Code, der zur Darstellung benötigt wird.

Auf meinem Blog nutze ich zur Darstellung von Codeausschnitten die Bibliothek highlight.js. Um Codes darzustellen, werden die beiden Shortcodes tk_code_begin und tk_code_end verwendet. Ein Codeausschnitt lässt sich in der WordPress-Benutzeroberfläche folgendermaßen darstellen:

<pre>[tk_code_begin block="true" lang="php"]    
if( false !== $k &amp;&amp; false === $is_contact_page 
   &amp;&amp; false === $is_rest_api ){
    unset( $plugins[$k] );
}
[tk_code_end]</pre>

Dieser Abschnitt wird beim Aufruf der Seite zweimal durchlaufen. Beim ersten Mal fügt der Shortcode tk_code_begin die benötigten CSS- und Javascript-Dateien hinzu. Dies macht der folgende Codeausschnitt:

$mod = new ModuleHighlightJS;
if( !$mod->initialize( $args ) ){
    return;
}
/* Code zum Rendern des Shortcodes */

Die Klasse ModuleHighlightJS enthält alle Routinen, zur Verwendung der Bibliothek highlight.js. Die Funktion initialize fügt die notwendigen CSS- und Javascript-Dateien mit den Funktionen wp_enqueue_* hinzu. Dabei ist es egal, ob die Funktionen wp_enqueue_* mehrmals für die gleichen Dateien aufgerufen werden, WordPress fügt die CSS- und Javascript-Dateien nur einmal hinzu. Im zweiten Durchlauf liefert die Funktion initialize den Wert true zurück, damit der Code zum Rendern des Shortcodes aufgerufen wird.

Der erste Aufruf der Shortcodes kann im Hook wp erfolgen. Dieser Hook wird aufgerufen, wenn WordPress komplett initialisiert ist und bevor die Seite gerendert wird. Somit stehen WordPress vor dem Rendern der Seite alle Stylesheets und andere Codes zu Verfügung, die auf der Seite eingefügt werden müssen. Der zweite Aufruf erfolgt folgendermaßen:

add_action( 'wp', 'tk_first_render' );
function tk_first_render( ){
	do_shortcode( get_the_content() );
}