Skip to content

Wszystko o WordPressie, tworzeniu stron — i nie tylko

⚡ Contact Form 7 -- odroczone ładowanie skryptów i stylów w celu przyspieszenia WordPressa

⚡ Contact Form 7 -- odroczone ładowanie skryptów i stylów w celu przyspieszenia WordPressa

Jak CF7 spowalnia witrynę i dlaczego można to naprawić w 5 minut

Contact Form 7 jest zainstalowany na ponad 5 milionach witryn WordPress. Wtyczka jest niezawodna, elastyczna i bezpłatna, a formularz kontaktowy na niej działa niemal wszędzie. Jednak ta wygoda ma swoją drugą stronę: domyślnie CF7 ładuje swoje CSS i JavaScript na każdą stronę witryny, nawet jeśli formularza tam nie ma.

Dla strony głównej, bloga, landing page'a i dziesiątek innych podstron jest to martwy balast: zbędne zapytania, wydłużony DOM Content Loaded, rozdęty rozmiar strony. W liczbach to około 10-30 KB skompresowanego transferu i 1-2 zapytania blokujące renderowanie zupełnie niepotrzebnie. PageSpeed Insights nie wybacza takich rzeczy.

Można to naprawić na trzy sposoby: od prymitywnego defer w dwóch linijkach po staranne warunkowe ładowanie „zgodnie z instrukcją" od twórcy wtyczki. Omówmy każdy z nich, z kodem i bez zbędnych słów.

💡 Szybki przegląd:

  • Wyłączenie globalnego ładowania CF7 przez stałe WPCF7_LOAD_JS i WPCF7_LOAD_CSS w wp-config.php, najczystsza oficjalna metoda.
  • Ponowne włączenie skryptów i stylów, ale tylko na stronach z formularzem, przez wpcf7_enqueue_scripts() w szablonie strony.
  • Dla niestandardowych pakietów, pakiet lazy-cf7-assets, który sam znajdzie formularz na stronie i załaduje JS dynamicznie.

Sposób 1: podłączenie skryptu CF7 z defer przez functions.php

Najszybsza i najprostsza opcja, dodanie atrybutu defer do skryptu Contact Form 7. Mówi on przeglądarce: „ładuj plik w tle, a wykonaj go, gdy DOM będzie gotowy". Formularz nadal działa, ale skrypt nie blokuje już renderowania strony.

Kod dodaje się w functions.php aktywnego motywu (lub przez wtyczkę Code Snippets, bezpieczniej przy aktualizacjach):

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}

Funkcja sprawdza URL każdego podłączanego skryptu przez hook clean_url. Jeśli adres zawiera contact-form-7 i rozszerzenie .js, dodaje defer='defer'. Wszystkich innych skryptów nie rusza.

Plus: rozwiązanie w 10 linijkach, nie wymaga edycji szablonów ani konfiguracji wtyczki. Pasuje do motywów, gdzie nie ma osobnego szablonu strony kontaktowej.

Minus: skrypt nadal ładuje się na każdej stronie, usuwa się jedynie blokowanie renderowania. Transfer i zapytania do serwera nie są redukowane. Ta metoda w ogóle nie dotyczy CSS wtyczki, arkusz stylów ładuje się jak zwykle.

Sposób 2: oficjalna metoda, warunkowe ładowanie przez stałe

To podejście jest opisane w dokumentacji Contact Form 7 przez samego twórcę wtyczki, Takayukiego Miyoshi. Pomysł składa się z dwóch kroków: najpierw globalnie wyłączamy skrypty i style CF7, a następnie włączamy je z powrotem, ale tylko na tych stronach, gdzie formularz jest faktycznie używany.

Krok 1: wyłączenie ładowania na wszystkich stronach

Dodaj w wp-config.php dwie stałe:

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

Alternatywnie, przez functions.php motywu:

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

Po tym CF7 nie załaduje ani jednej linii swojego kodu na żadnej stronie witryny, w tym na tych, gdzie formularz się znajduje. Formularz bez skryptów traci wysyłanie AJAX i walidację, dlatego potrzebny jest krok 2.

Krok 2: przywrócić skrypty na stronach z formularzem

Załóżmy, że Pana/Pani strona kontaktowa używa szablonu page-contact.php w folderze motywu. Proszę dodać w tym szablonie przed wywołaniem wp_head():

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

Funkcje wpcf7_enqueue_scripts() i wpcf7_enqueue_styles() ręcznie ustawiają skrypty i style CF7 w kolejce tylko dla tego szablonu. Wszystkie pozostałe strony witryny pozostają czyste.

Plus: metoda „od producenta", gwarantuje, że nie ulegnie uszkodzeniu podczas aktualizacji wtyczki. Działa z CF7 w wersji 5.x i 6.x, aktualna 6.1.6 na czerwiec 2026 (lista wydań). Zerowe zbędne ładowanie na stronach bez formularza.

Minus: wymaga edycji szablonów motywu. Jeśli stron z formularzem jest kilka, trzeba pamiętać o dodaniu wywołań w każdym szablonie. Jeśli formularz został wstawiony shortcodem w treści (a nie w szablonie), metoda nie zadziała bez dodatkowych warunków.

Sposób 3: pakiet lazy-cf7-assets dla paczek JavaScript

Jeśli buduje Pan/Pani frontend przez bundler (Webpack, Vite, esbuild) i używa nowoczesnego motywu z niestandardową paczką JavaScript, dostępny jest pakiet npm lazy-cf7-assets. Rozwiązuje on to samo zadanie, ale po stronie klienta: skanuje DOM, znajduje formularz CF7 i dopiero wtedy dynamicznie ładuje skrypty wtyczki.

Instalacja:

1npm install lazy-cf7-assets

Przed użyciem należy wyłączyć automatyczne ładowanie JS wtyczki (jak w sposobie 2, przez wpcf7_load_js):

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

Następnie w Pana/Pani paczce JS:

1import lazyform from 'lazy-cf7-assets';
2
3// Инициализация после готовности DOM
4lazyform.init();

Jeśli skrypty ładują się w <head>, a nie na końcu <body>, proszę podać bezwzględną ścieżkę do obrazka GIF ładowania, aby formularz nie „migał" pustym stanem:

1lazyform.init({
2 gifPath: '/wp-content/themes/my-theme/images/ajax-loader.gif'
3});
Zrzut ekranu repozytorium lazy-cf7-assets na GitHubie

Plus: zero dotyku po stronie PHP, nie trzeba edytować szablonów dla każdej strony z formularzem. Pakiet sam określi, czy na stronie znajduje się shortcode CF7, i załaduje skrypty tylko wtedy. Pasuje do witryn, gdzie formularz jest wyświetlany przez shortcode w treści (a nie na sztywno w szablonie).

Minus: działa tylko z JavaScript (CSS wtyczki nadal trzeba wyłączać osobno). Wymaga obecności bundlera w projekcie. Pakiet jest minimalny (1 gwiazdka na GitHubie), wspierany przez jednego dewelopera, do produkcji warto zrobić forka i sprawdzać aktualizacje CF7 pod kątem kompatybilności.

Co wybrać: porównanie trzech podejść

Kryterium

defer przez hook

Stałe + szablon

lazy-cf7-assets

Oszczędność transferu

❌ nie

✅ pełna

✅ pełna (JS)

Ochrona przed aktualizacjami CF7

✅ tak

✅ tak

wymaga sprawdzenia

Nie wymaga edycji szablonów

✅ tak

❌ nie

✅ tak

Wyłącza CSS

❌ nie

✅ tak

❌ nie

Złożoność wdrożenia

niska

średnia

średnia

Shortcode formularza w treści

✅ działa

❌ trudności

✅ działa

Jeśli formularz znajduje się na jednej stronie w osobnym szablonie, proszę wybrać sposób 2 (oficjalna metoda). Jeśli witryna działa na nowoczesnym bundlerze i formularzy może być kilka w różnych miejscach, sposób 3 (lazy-cf7-assets). Jeśli potrzebne jest rozwiązanie „od ręki" bez edycji szablonów, sposób 1 (defer), ale proszę pamiętać o limitach.

Jeden ważny niuans: po każdej z tych zmian koniecznie proszę sprawdzić, czy formularz się wysyła, walidacja działa, reCAPTCHA nie uległa uszkodzeniu, a style nie rozjechały się. Proszę otworzyć stronę z formularzem w trybie incognito, wypełnić i wysłać testową wiadomość przed i po.

⁉️🤔 Często zadawane pytania

Dlaczego CF7 w ogóle ładuje skrypty na wszystkich stronach?

Wtyczka na etapie ładowania WordPressa nie wie, czy na danej stronie znajduje się shortcode formularza. WordPress składa stronę później, gdy kolejka skryptów jest już utworzona. Twórca, Takayuki Miyoshi, wyjaśnia to w oficjalnej dokumentacji: technicznie niemożliwe jest wykrycie shortcode’u przed akcją wp_head. Dlatego przyjęto konserwatywne podejście, by ładować zawsze. To świadoma decyzja architektoniczna, a nie błąd: wtyczka poświęca wydajność na rzecz gwarantowanego działania. Ciężar optymalizacji zostaje przeniesiony na developera strony.

Czy formularz przestanie działać po wyłączeniu globalnego ładowania?

Nie, jeśli starannie włączy się skrypty z powrotem na potrzebnych stronach. Formularz straci wysyłanie AJAX i walidację po stronie klienta tylko na tych stronach, gdzie skrypty nie są podłączone. Dlatego krok 2 (przywrócenie skryptów) jest obowiązkowy, nie należy zatrzymywać się na samym WPCF7_LOAD_JS = false. Proszę sprawdzić kolejność wywołań: wpcf7_enqueue_scripts() musi być przed wp_head(), a nie po. I proszę się upewnić, że reCAPTCHA nie koliduje z ładowaniem z atrybutem defer.

Czy metoda ze stałymi działa w CF7 6.x?

Tak, stałe WPCF7_LOAD_JS i WPCF7_LOAD_CSS są w pełni wspierane w aktualnej wersji 6.1.6 (zob. oficjalny dziennik wersji). W całej historii wtyczki, od wersji 3.9 do obecnej 6.x, stałe te ani razu nie zostały uznane za przestarzałe. To najstabilniejszy i udokumentowany sposób zarządzania ładowaniem.

Co zrobić, gdy formularzy jest kilka i znajdują się w różnych miejscach?

Jeśli formularze są rozrzucone po różnych stronach za pomocą shortcode’ów w treści (a nie w szablonach), oficjalna metoda z szablonami jest niewygodna. Proszę użyć albo lazy-cf7-assets (sposób 3), albo wtyczki Conditionally Load CF7: dodaje ona w panelu administracyjnym ustawienia, na których stronach/typach wpisów włączać skrypty, i działa bez edycji kodu.

Trzy linijki kodu kontra kilkanaście zapytań

Problem „CF7 ładuje skrypty wszędzie" istnieje dokładnie tak długo, jak sama wtyczka, a przez ponad 10 lat twórca nie zmienił domyślnego zachowania, ponieważ jest to kompromis między prostotą a wydajnością. Ale kompromis to nie wyrok.

Najbezpieczniejszą ścieżką jest oficjalna metoda ze stałymi i szablonami. Usuwa ona skrypty i style wtyczki ze wszystkich stron oprócz tych, gdzie są potrzebne, i nie psuje się podczas aktualizacji. Jeśli strona działa na nowoczesnym stosie z bundlerem, warto przyjrzeć się lazy-cf7-assets. Jeśli potrzebne jest szybkie rozwiązanie bez edycji szablonów, defer przez filtr clean_url da wzrost w metrykach już dziś.

Proszę sprawdzić swoją stronę w PageSpeed Insights przed i po, zmniejszenie liczby zapytań blokujących o 1-2 jednostki oraz oszczędność 10-30 KB na stronę mogą podnieść wskaźnik Wydajności o 2-5 punktów, szczególnie na urządzeniach mobilnych.