Optymalizacja wydajności przez functions.php: Selektywne wyrejestrowywanie skryptów wtyczek WordPressa

Spis treści
Przegląd architektury: Mechanizm zarządzania zasobami w WordPressie
Współczesne instalacje WordPressa nierzadko zmagają się z nadmiarem kodu CSS i JavaScript generowanym przez wtyczki firm trzecich. Domyślnie wiele zaawansowanych rozszerzeń – takich jak platformy e-commerce, generatory formularzy czy narzędzia do kolorowania składni – rejestruje i ładuje swoje statyczne zasoby globalnie na każdym adresie URL w warstwie frontowej. Bezwarunkowe ładowanie plików zwiększa rozmiar struktury DOM, generuje niepotrzebne żądania HTTP i obniża wskaźniki Core Web Vitals, w tym Largest Contentful Paint (LCP) oraz Interaction to Next Paint (INP).
W WordPressie w wersji 7.0.2 cykl życia zasobów opiera się na klasach WP_Scripts oraz WP_Styles. Pliki są dodawane do kolejki podczas wykonywania akcji wp_enqueue_scripts. W celu wyeliminowania zbędnych zasobów z przeglądarki bez naruszania funkcjonalności wtyczek na stronach docelowych, konieczne jest wdrożenie selektywnego wyrejestrowywania (dequeuing) z poziomu pliku functions.php aktywnego motywu lub za pomocą wtyczki Must-Use (MU-plugin).

Instrukcja wdrożenia krok po kroku
Krok 1: Audyt i identyfikacja zarejestrowanych uchwytów (Handles)
Przed usunięciem zasobu z kolejki należy zidentyfikować jego unikalny uchwyt (handle). WordPress przypisuje określony ciąg znaków do każdego arkusza stylów i pliku skryptu podczas rejestracji funkcjami wp_register_script() lub wp_register_style().
W celu sprawdzenia uchwytów załadowanych na danym adresie URL, możliwe jest tymczasowe dodanie poniższego kodu diagnostycznego do pliku functions.php, co spowoduje zapisanie listy aktywnych skryptów do logu serwera PHP:
add_action( 'wp_print_scripts', function() {
if ( ! is_admin() ) {
global $wp_scripts;
error_log( 'Enqueued Scripts: ' . implode( ', ', $wp_scripts->queue ) );
}
}, 9999 );
add_action( 'wp_print_styles', function() {
if ( ! is_admin() ) {
global $wp_styles;
error_log( 'Enqueued Styles: ' . implode( ', ', $wp_styles->queue ) );
}
}, 9999 );
Krok 2: Priorytety haków (Hooks) i kontekst wywołania
Próba usunięcia zasobu przed jego załadowaniem przez wtyczkę kończy się niepowodzeniem. Większość standardowych wtyczek podpina funkcje ładujące pod hak wp_enqueue_scripts z domyślnym priorytetem 10.
Z tego względu funkcja usuwająca musi zostać powiązana z hakiem wp_enqueue_scripts z wyższym priorytetem liczbowym (np. 100 lub 999). Gwarantuje to wykonanie procedury czyszczącej dopiero po zakończeniu rejestracji zasobów przez wtyczki.
Krok 3: Programowanie logiki selektywnego wyrejestrowywania
Kluczowe funkcje służące do usuwania zasobów z kolejki WordPressa to:
wp_dequeue_script( $handle )– Usuwa plik JavaScript z aktywnej kolejki ładowania.wp_deregister_script( $handle )– Całkowicie wyrejestrowuje uchwyt skryptu z systemu.wp_dequeue_style( $handle )– Usuwa arkusz CSS z aktywnej kolejki ładowania.wp_deregister_style( $handle )– Całkowicie wyrejestrowuje uchwyt arkusza stylów.
Połączenie operacji dequeue i deregister zapobiega sytuacjom, w których skrypty zależne (dependencies) automatycznie wymuszają ponowne załadowanie usuniętego zasobu nadrzędnego; same skrypty zależne również przestają być wtedy wstawiane do strony.
Krok 4: Wdrożenie kodu produkcyjnego dla WooCommerce i formularzy
Poniższa architektura demonstruje sposób blokowania zasobów WooCommerce oraz skryptów formularzy kontaktowych na standardowych wpisach blogowych i stronach informacyjnych:
/**
* Architektura selektywnego usuwania zasobów
* Cel: WordPress v7.0.2
*/
add_action( 'wp_enqueue_scripts', 'lw_selective_asset_cleanup', 100 );
function lw_selective_asset_cleanup() {
// Przerwanie wykonywania kodu w panelu administracyjnym WordPressa
if ( is_admin() ) {
return;
}
// 1. Usunięcie zasobów e-commerce ze standardowych artykułów i stron treści
if ( function_exists( 'is_woocommerce' ) && ! is_woocommerce() && ! is_cart() && ! is_checkout() ) {
// Usunięcie skryptów JavaScript WooCommerce
wp_dequeue_script( 'woocommerce' );
wp_deregister_script( 'woocommerce' );
wp_dequeue_script( 'wc-add-to-cart' );
wp_deregister_script( 'wc-add-to-cart' );
wp_dequeue_script( 'wc-cart-fragments' );
wp_deregister_script( 'wc-cart-fragments' );
// Usunięcie arkuszy stylów WooCommerce
wp_dequeue_style( 'woocommerce-general' );
wp_deregister_style( 'woocommerce-general' );
wp_dequeue_style( 'woocommerce-layout' );
wp_deregister_style( 'woocommerce-layout' );
wp_dequeue_style( 'woocommerce-smallscreen' );
wp_deregister_style( 'woocommerce-smallscreen' );
}
// 2. Usunięcie skryptów formularza z podstron nieposiadających formularzy
if ( ! is_page( 'contact' ) && ! is_page( 'support' ) ) {
wp_dequeue_script( 'contact-form-7' );
wp_deregister_script( 'contact-form-7' );
wp_dequeue_style( 'contact-form-7' );
wp_deregister_style( 'contact-form-7' );
}
}
Krok 5: Kontrola jakości i testy regresyjne
Po wdrożeniu kodu do środowiska produkcyjnego wymagane jest przeprowadzenie procedury weryfikacyjnej:
- Analiza zakładki Network: Otwarcie narzędzi deweloperskich (F12) na standardowym artykule blogowym i potwierdzenie braku żądań dla docelowych plików
.jsoraz.css. - Weryfikacja funkcjonalna: Sprawdzenie stron docelowych, które wymagają usuniętych zasobów (np. koszyk lub podstrona kontaktowa), w celu upewnienia się, że instrukcje warunkowe działają poprawnie.
- Monitorowanie błędów w konsoli: Kontrola konsoli przeglądarki pod kątem braku błędów JavaScript wynikających z braku zdefiniowanych bibliotek globalnych.
Podsumowanie i mierzalna wartość dodana
Co da się osiągnąć dzięki instrukcji: Zastąpienie bezwarunkowego, globalnego ładowania zasobów przez precyzyjne zarządzanie zależnościami na poziomie konkretnych adresów URL. Pliki wtyczek są wywoływane wyłącznie tam, gdzie ich obecność jest technicznie uzasadniona.
Wynikająca z tego wartość dodana:
- Drastyczna redukcja wagi strony: Łączny rozmiar przesyłanych danych na stronach artykułów zmniejsza się o 300–800 KB w zależności od liczby zainstalowanych wtyczek.
- Eliminacja nieużywanego kodu: Audyty w Google PageSpeed Insights wykazują natychmiastowe rozwiązanie problemów „Zmniejsz nieużywany kod JavaScript” oraz „Zmniejsz nieużywany kod CSS”.
- Poprawa wskaźników Core Web Vitals: Odciążenie wątku głównego przeglądarki (Main Thread) prowadzi do redukcji wskaźnika Total Blocking Time (TBT) oraz optymalizacji INP, co bezkolizyjnie podnosi potencjał rankingowy w organicznych wynikach wyszukiwania.
Pytania i odpowiedzi
Dlaczego wp_deregister_script() może usunąć więcej skryptów, niż zamierzano?
Ponieważ WordPress wstawia skrypt do strony tylko wtedy, gdy zarejestrowane są wszystkie uchwyty, od których on zależy. Wyrejestrowanie uchwytu usuwa więc także wszystkie skrypty, które podają go jako zależność, również skrypty innych wtyczek, a w normalnej pracy strona nie pokazuje przy tym żadnego błędu. Widać to w analizie zakładki Network z kroku 5: plik, którego po zmianie brakuje, choć nie było go na liście, zależał od usuniętego uchwytu.
Na co zwrócić uwagę przy warunku formularza kontaktowego w witrynie wielojęzycznej?
is_page() porównuje z identyfikatorem, slugiem albo tytułem wywołanej strony. W witrynie wielojęzycznej każde tłumaczenie jest osobną stroną z własnym identyfikatorem i zwykle własnym slugiem. Warunek z kroku 4 rozpoznaje więc tylko stronę ze slugiem contact; na /de/kontakt/ czy /pl/kontakt/ skrypt formularza zostaje usunięty, a formularz działa tam bez skryptu, na którym się opiera.
Są dwa sposoby, by to naprawić:
- is_page() przyjmuje także listę, na przykład
is_page( array( 'contact', 'kontakt', 'support' ) ). To proste, ale wymaga uzupełniania przy każdym nowym języku lub nowej stronie z formularzem. - Warunek sprawdza zamiast tego, czy treść zawiera shortcode:
is_singular() && has_shortcode( get_post()->post_content, 'contact-form-7' ). Taki warunek podąża za formularzem, a nie za adresem, ale nie wykrywa formularzy umieszczonych w widżecie albo w szablonie motywu.
Który sposób pasuje, rozstrzyga weryfikacja funkcjonalna z kroku 5, przeprowadzona na każdej wersji językowej stron z formularzem, a nie tylko na pierwszej.