Skip to content

Alles für WordPress, Webentwicklung — und mehr

⚡ Contact Form 7 - verzögertes Laden von Skripten und Styles zur Beschleunigung von WordPress

⚡ Contact Form 7 - verzögertes Laden von Skripten und Styles zur Beschleunigung von WordPress

Wie CF7 Ihre Website ausbremst und warum Sie das in 5 Minuten beheben können

Contact Form 7 ist auf über 5 Millionen WordPress-Installationen im Einsatz. Das Plugin ist zuverlässig, flexibel und kostenlos, und damit gebaute Kontaktformulare funktionieren auf praktisch jeder Website. Doch dieser Komfort hat eine Kehrseite: Standardmäßig lädt CF7 sein CSS und JavaScript auf jeder Seite Ihrer Website, selbst wenn dort weit und breit kein Formular existiert.

Für die Startseite, den Blog, Landingpages und Dutzende anderer Seiten ist das tote Last: zusätzliche Requests, eine erhöhte DOM-Content-Loaded-Zeit, aufgeblähte Seitengröße. In Zahlen ausgedrückt: rund 10 bis 30 KB komprimiertes Datenvolumen und 1 bis 2 blockierende Requests ohne jeden Nutzen. PageSpeed Insights verzeiht so etwas nicht.

Das lässt sich auf drei Arten beheben, von einem einfachen Zwei-Zeilen-Defer bis hin zum sorgfältigen Conditional Loading „nach Vorschrift" des Plugin-Entwicklers. Wir behandeln jede Variante, mit Code und ohne überflüssiges Beiwerk.

💡 Kurzüberblick:

  • Globales CF7-Laden über die Konstanten WPCF7_LOAD_JS und WPCF7_LOAD_CSS in der wp-config.php deaktivieren, die sauberste offizielle Methode.
  • Skripte und Styles wieder aktivieren, aber nur auf Seiten mit einem Formular, über wpcf7_enqueue_scripts() im Seiten-Template.
  • Für eigene Bundles das Paket lazy-cf7-assets, das automatisch das Formular auf der Seite erkennt und JS dynamisch lädt.

Methode 1: CF7-Skript per functions.php mit defer laden

Die schnellste und einfachste Möglichkeit besteht darin, dem Contact Form 7-Skript das Attribut defer hinzuzufügen. Es weist den Browser an: „Lade die Datei im Hintergrund, führe sie aber erst aus, wenn das DOM bereit ist". Das Formular funktioniert weiterhin, aber das Skript blockiert nicht länger das Rendern der Seite.

Fügen Sie diesen Code in die functions.php Ihres aktiven Themes ein (oder über das Code-Snippets-Plugin, sicherer bei Updates):

1if ( ! function_exists( 'add_defer_to_cf7' ) ) {
2 function add_defer_to_cf7( $url ) {
3 if (
4 false === strpos( $url, 'contact-form-7' ) ||
5 false === strpos( $url, '.js' )
6 ) {
7 return $url;
8 }
9 return "$url' defer='defer";
10 }
11 add_filter( 'clean_url', 'add_defer_to_cf7', 11, 1 );
12}

Die Funktion prüft die URL jedes eingereihten Skripts über den clean_url-Hook. Enthält die Adresse contact-form-7 und die Endung .js, wird defer='defer' hinzugefügt. Alle anderen Skripte bleiben unverändert.

Vorteil: eine Lösung in 10 Zeilen, die kein Bearbeiten von Templates oder der Plugin-Konfiguration erfordert. Geeignet für Themes, bei denen es kein separates Kontaktseiten-Template gibt.

Nachteil: das Skript wird weiterhin auf jeder Seite geladen, Sie entfernen lediglich das renderblockierende Verhalten. Datenvolumen und Server-Requests werden nicht reduziert. Diese Methode wirkt sich überhaupt nicht auf das CSS des Plugins aus, das Stylesheet wird wie gewohnt geladen.

Methode 2: offizielle Methode, Conditional Loading über Konstanten

Dieser Ansatz ist in der Contact-Form-7-Dokumentation vom Plugin-Entwickler selbst, Takayuki Miyoshi, beschrieben. Die Idee besteht aus zwei Schritten: zunächst CF7-Skripte und -Styles global deaktivieren, um sie anschließend wieder zu aktivieren, aber nur auf Seiten, auf denen das Formular tatsächlich genutzt wird.

Schritt 1: Laden auf allen Seiten deaktivieren

Fügen Sie zwei Konstanten in die wp-config.php ein:

1define( 'WPCF7_LOAD_JS', false );
2define( 'WPCF7_LOAD_CSS', false );

Alternativ über die functions.php Ihres Themes:

1add_filter( 'wpcf7_load_js', '__return_false' );
2add_filter( 'wpcf7_load_css', '__return_false' );

Danach lädt CF7 auf keiner Seite Ihrer Website mehr eine einzige Codezeile, auch nicht auf Seiten, auf denen ein Formular vorhanden ist. Ohne Skripte verliert das Formular die AJAX-Übermittlung und Validierung, daher ist Schritt 2 erforderlich.

Schritt 2: Skripte auf Seiten mit einem Formular wiederherstellen

Angenommen, Ihre Kontaktseite verwendet das Template page-contact.php in Ihrem Theme-Ordner. Fügen Sie Folgendes in dieses Template ein, bevor wp_head() aufgerufen wird:

1if ( function_exists( 'wpcf7_enqueue_scripts' ) ) {
2 wpcf7_enqueue_scripts();
3}
4
5if ( function_exists( 'wpcf7_enqueue_styles' ) ) {
6 wpcf7_enqueue_styles();
7}

Die Funktionen wpcf7_enqueue_scripts() und wpcf7_enqueue_styles() binden CF7-Skripte und -Styles manuell nur in diesem Template ein. Alle anderen Seiten Ihrer Website bleiben sauber.

Vorteil: Die Methode stammt „vom Hersteller", garantiert keine Probleme bei Plugin-Updates. Funktioniert mit CF7-Versionen 5.x und 6.x, aktuelle Version 6.1.6 Stand Juni 2026 (Release-Liste). Keinerlei unnötiges Laden auf Seiten ohne Formular.

Nachteil: Erfordert die Bearbeitung von Theme-Templates. Wenn Sie mehrere Seiten mit Formularen haben, müssen Sie daran denken, die Aufrufe in jedes Template einzufügen. Wird das Formular per Shortcode im Content eingefügt (statt im Template), funktioniert die Methode nicht ohne zusätzliche Bedingungen.

Methode 3: Das lazy-cf7-assets-Paket für JavaScript-Bundles

Wenn Sie Ihr Frontend mit einem Bundler (Webpack, Vite, esbuild) erstellen und ein modernes Theme mit einem eigenen JavaScript-Bundle verwenden, gibt es ein npm-Paket namens lazy-cf7-assets. Es löst dasselbe Problem, jedoch auf der Client-Seite: Es durchsucht das DOM, findet das CF7-Formular und lädt erst dann dynamisch die Plugin-Skripte.

Installation:

1npm install lazy-cf7-assets

Bevor Sie es nutzen, müssen Sie das automatische JS-Laden durch das Plugin deaktivieren (wie in Methode 2, über wpcf7_load_js):

1add_filter( 'wpcf7_load_js', '__return_false' );

Dann in Ihrem JS-Bundle:

1import lazyform from 'lazy-cf7-assets';
2
3// Initialize after DOM ready
4lazyform.init();

Wenn Skripte im <head> statt am Ende des <body> geladen werden, geben Sie einen absoluten Pfad zum Lade-GIF an, damit das Formular nicht in leerem Zustand „flackert":

1lazyform.init({
2 gifPath: '/wp-content/themes/my-theme/images/ajax-loader.gif'
3});
Screenshot des lazy-cf7-assets-Repositorys auf GitHub

Vorteil: Kein Eingriff auf der PHP-Seite, keine Notwendigkeit, Templates für jede Seite mit einem Formular zu bearbeiten. Das Paket erkennt automatisch, ob ein CF7-Shortcode auf der Seite existiert, und lädt Skripte nur dann. Geeignet für Websites, bei denen das Formular per Shortcode im Content ausgegeben wird (statt fest im Template codiert).

Nachteil: Funktioniert nur mit JavaScript (das CSS des Plugins muss weiterhin separat deaktiviert werden). Setzt einen Bundler im Projekt voraus. Das Paket ist minimal (1 Stern auf GitHub), wird von einem einzelnen Entwickler gepflegt, für den Produktiveinsatz sollten Sie es forken und CF7-Updates auf Kompatibilität prüfen.

Was Sie wählen sollten: Vergleich der drei Ansätze

Kriterium

Defer via Hook

Konstanten + Template

lazy-cf7-assets

Traffic-Ersparnis

❌ nein

✅ vollständig

✅ vollständig (JS)

Schutz vor CF7-Updates

✅ ja

✅ ja

erfordert Prüfung

Keine Template-Bearbeitung nötig

✅ ja

❌ nein

✅ ja

Deaktiviert CSS

❌ nein

✅ ja

❌ nein

Komplexität der Implementierung

gering

mittel

mittel

Formular-Shortcode im Content

✅ funktioniert

❌ Schwierigkeiten

✅ funktioniert

Wenn Ihr Formular auf einer einzelnen Seite in einem separaten Template lebt, nutzen Sie Methode 2 (offizielle Methode). Wenn die Website einen modernen Bundler verwendet und Sie möglicherweise mehrere Formulare an verschiedenen Stellen haben, Methode 3 (lazy-cf7-assets). Wenn Sie eine Lösung „sofort" ohne Template-Bearbeitung benötigen, Methode 1 (Defer), aber bedenken Sie die Einschränkungen.

Ein wichtiger Hinweis: Stellen Sie nach jeder dieser Änderungen unbedingt sicher, dass das Formular sendet, die Validierung funktioniert, reCAPTCHA nicht defekt ist und sich die Styles nicht verschoben haben. Öffnen Sie die Seite mit dem Formular im Inkognito-Modus, füllen Sie vorher und nachher eine Testnachricht aus und senden Sie sie ab.

⁉️🤔 Häufig gestellte Fragen

Warum lädt CF7 überhaupt Skripte auf allen Seiten?

Das Plugin kann zum Ladezeitpunkt von WordPress nicht wissen, ob eine bestimmte Seite einen Formular-Shortcode enthält. WordPress setzt die Seite später zusammen, wenn die Skript-Warteschlange bereits gebildet wurde. Der Entwickler Takayuki Miyoshi erläutert dies in der offiziellen Dokumentation: Es ist technisch unmöglich, das Vorhandensein eines Shortcodes vor dem wp_head-Hook zu erkennen. Daher wurde ein konservativer Ansatz gewählt, immer zu laden. Dies ist eine bewusste Architekturentscheidung, kein Fehler: Das Plugin opfert Performance zugunsten garantierter Funktionalität. Die Last der Optimierung wird auf den Seitenentwickler übertragen.

Geht das Formular kaputt, wenn man das globale Laden deaktiviert?

Nein, sofern Sie die Skripte auf den benötigten Seiten sorgfältig wieder aktivieren. Das Formular verliert die AJAX-Übermittlung und die clientseitige Validierung nur auf Seiten, auf denen die Skripte nicht eingebunden sind. Deshalb ist Schritt 2 (Wiederherstellen der Skripte) zwingend erforderlich, bleiben Sie nicht bei WPCF7_LOAD_JS = false stehen. Prüfen Sie die Reihenfolge der Aufrufe: wpcf7_enqueue_scripts() muss vor wp_head() kommen, nicht danach. Und stellen Sie sicher, dass reCAPTCHA nicht mit dem verzögerten Laden kollidiert.

Funktioniert die Konstanten-Methode mit CF7 6.x?

Ja, die Konstanten WPCF7_LOAD_JS und WPCF7_LOAD_CSS werden in der aktuellen Version 6.1.6 vollständig unterstützt (siehe offizielles Versionsprotokoll). In der gesamten Historie des Plugins, von Version 3.9 bis zur aktuellen Version 6.x, wurden diese Konstanten nie als veraltet deklariert. Dies ist die stabilste und am besten dokumentierte Methode zur Steuerung des Ladeverhaltens.

Was tun, wenn ich mehrere Formulare an verschiedenen Stellen habe?

Wenn Formulare über Shortcodes in Inhalten (nicht in Templates) auf verschiedene Seiten verteilt sind, ist die offizielle Methode mit Templates unpraktisch. Verwenden Sie entweder lazy-cf7-assets (Methode 3) oder das Plugin Conditionally Load CF7: Es fügt im Admin-Bereich eine Einstellung hinzu, für welche Seiten/Beitragstypen Skripte geladen werden sollen, und funktioniert ohne Code-Änderungen.

Drei Codezeilen gegen Dutzende von Requests

Das Problem „CF7 lädt Skripte überall" existiert genau so lange wie das Plugin selbst, und seit über 10 Jahren hat der Entwickler das Standardverhalten nicht geändert, weil es ein Kompromiss zwischen Einfachheit und Performance ist. Aber ein Kompromiss, kein Urteil.

Der sicherste Weg ist die offizielle Methode mit Konstanten und Templates. Sie entfernt die Skripte und Styles des Plugins von allen Seiten außer jenen, auf denen sie benötigt werden, und geht bei Updates nicht kaputt. Wenn Ihre Seite einen modernen Stack mit einem Bundler nutzt, werfen Sie einen Blick auf lazy-cf7-assets. Benötigen Sie etwas Schnelles ohne Template-Änderungen, bringt Ihnen das Verzögern über den clean_url-Hook noch heute messbare Verbesserungen.

Prüfen Sie Ihre Seite vorher und nachher mit PageSpeed Insights: Die Reduzierung blockierender Requests um 1 bis 2 Einheiten und die Einsparung von 10 bis 30 KB pro Seite können den Performance-Score um 2 bis 5 Punkte steigern, besonders auf mobilen Geräten.