
⚡ Contact Form 7 — відкладене завантаження скриптів і стилів для прискорення WordPress
Як CF7 уповільнює сайт і чому це можна виправити за 5 хвилин
Contact Form 7 встановлений на понад 5 мільйонах сайтів WordPress. Плагін надійний, гнучкий і безплатний, форма зворотного зв’язку на ньому працює майже в усіх. Але ця зручність має зворотний бік: за замовчуванням CF7 підвантажує свої CSS і JavaScript на кожну сторінку сайту, навіть якщо форми там немає й близько.
Для головної, блогу, лендингу та десятка інших сторінок це мертвий вантаж: зайві запити, збільшений DOM Content Loaded, роздутий розмір сторінки. У цифрах це приблизно 10-30 КБ стисненого трафіку та 1-2 блокувальні запити на рівному місці. PageSpeed Insights такого не пробачає.
Виправляється це трьома способами: від примітивного defer у два рядки до акуратного умовного завантаження «за підручником» від розробника плагіна. Розберемо кожен, із кодом і без зайвого.
💡 Швидкий огляд:
- Вимкнути глобальне завантаження CF7 через константи
WPCF7_LOAD_JSіWPCF7_LOAD_CSSуwp-config.php, найчистіший офіційний спосіб. - Увімкнути скрипти та стилі назад, але лише на сторінках із формою, через
wpcf7_enqueue_scripts()у шаблоні сторінки. - Для кастомних бандлів, пакет
lazy-cf7-assets, який сам знайде форму на сторінці та підвантажить JS динамічно.
Спосіб 1: defer-підключення скрипту CF7 через functions.php
Найшвидший і найпростіший варіант, додати атрибут defer до скрипту Contact Form 7. Він каже браузеру: «завантажуй файл у фоновому режимі, а виконуй, коли DOM буде готовий». Форма продовжує працювати, але скрипт більше не блокує відтворення сторінки.
Код додається у functions.php активної теми (або через плагін Code Snippets, безпечніше під час оновлень):
1 if ( ! 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 }
Функція перевіряє URL кожного скрипту, що підключається, через хук clean_url. Якщо в адресі є contact-form-7 і розширення .js, додає defer='defer'. Усі інші скрипти не чіпає.
Плюс: рішення в 10 рядків, не потребує правлення шаблонів чи конфігурації плагіна. Підходить для тем, де немає окремого шаблону сторінки контактів.
Мінус: скрипт усе ще завантажується на кожній сторінці, ви просто прибираєте блокування рендерингу. Трафік і запити до сервера не скорочуються. CSS плагіна цей метод узагалі не зачіпає, таблиця стилів вантажиться як зазвичай.
Спосіб 2: офіційний метод, умовне завантаження через константи
Цей підхід описаний у документації Contact Form 7 самим розробником плагіна, Такаюкі Мійосі. Ідея у два кроки: спочатку глобально вимикаємо скрипти та стилі CF7, потім вмикаємо їх назад, але лише на тих сторінках, де форма реально використовується.
Крок 1: вимкнути завантаження на всіх сторінках
Додайте у wp-config.php дві константи:
1 define( 'WPCF7_LOAD_JS', false ); 2 define( 'WPCF7_LOAD_CSS', false );
Альтернативно, через functions.php теми:
1 add_filter( 'wpcf7_load_js', '__return_false' ); 2 add_filter( 'wpcf7_load_css', '__return_false' );
Після цього CF7 не завантажить жодного рядка свого коду на жодній сторінці сайту, включно з тими, де форма є. Форма без скриптів втрачає AJAX-відправлення та валідацію, тому потрібен крок 2.
Крок 2: повернути скрипти на сторінки з формою
Припустімо, ваша сторінка контактів використовує шаблон page-contact.php у папці теми. Додайте в цей шаблон до виклику wp_head():
1 if ( function_exists( 'wpcf7_enqueue_scripts' ) ) { 2 wpcf7_enqueue_scripts(); 3 } 4 5 if ( function_exists( 'wpcf7_enqueue_styles' ) ) { 6 wpcf7_enqueue_styles(); 7 }
Функції wpcf7_enqueue_scripts() і wpcf7_enqueue_styles() вручну ставлять скрипти та стилі CF7 у чергу лише на цьому шаблоні. Усі інші сторінки сайту залишаються чистими.
Плюс: метод «від виробника», гарантовано не зламається під час оновлення плагіна. Працює з CF7 версії 5.x і 6.x, актуальна 6.1.6 на червень 2026 (список релізів). Нульове зайве завантаження на сторінках без форми.
Мінус: потребує правлення шаблонів теми. Якщо сторінок із формою кілька, потрібно не забути додати виклики в кожен шаблон. Якщо форму вставлено шорткодом у контент (а не в шаблон), метод не спрацює без додаткових умов.
Спосіб 3: пакет lazy-cf7-assets для JavaScript-бандлів
Якщо ви збираєте фронтенд через бандлер (Webpack, Vite, esbuild) і використовуєте сучасну тему з кастомним JavaScript-бандлом, є npm-пакет lazy-cf7-assets. Він вирішує те саме завдання, але на стороні клієнта: сканує DOM, знаходить форму CF7 і лише після цього динамічно підвантажує скрипти плагіна.
Встановлення:
1 npm install lazy-cf7-assets
Перед використанням потрібно вимкнути автоматичне завантаження JS плагіна (як у способі 2, через wpcf7_load_js):
1 add_filter( 'wpcf7_load_js', '__return_false' );
Потім у вашому JS-бандлі:
1 import lazyform from 'lazy-cf7-assets'; 2 3 // Инициализация после готовности DOM 4 lazyform.init();
Якщо скрипти завантажуються в <head>, а не в кінці <body>, вкажіть абсолютний шлях до завантажувальної GIF-картинки, щоб форма не «блимала» порожнім станом:
1 lazyform.init({ 2 gifPath: '/wp-content/themes/my-theme/images/ajax-loader.gif' 3 });

Плюс: zero-touch на стороні PHP, не потрібно правити шаблони під кожну сторінку з формою. Пакет сам визначить, чи є на сторінці шорткод CF7, і завантажить скрипти лише тоді. Підходить для сайтів, де форма виводиться через шорткод у контенті (а не жорстко в шаблоні).
Мінус: працює лише з JavaScript (CSS плагіна, як і раніше, потрібно вимикати окремо). Потребує наявності бандлера в проєкті. Пакет мінімальний (1 зірка на GitHub), підтримується одним розробником, для production варто форкнути й перевіряти оновлення CF7 на сумісність.
Що обрати: порівняння трьох підходів
Критерій | defer через хук | Константи + шаблон | lazy-cf7-assets |
|---|---|---|---|
Економія трафіку | ❌ ні | ✅ повна | ✅ повна (JS) |
Захист від оновлень CF7 | ✅ так | ✅ так | потрібна перевірка |
Не потребує правлення шаблонів | ✅ так | ❌ ні | ✅ так |
Вимикає CSS | ❌ ні | ✅ так | ❌ ні |
Складність впровадження | низька | середня | середня |
Шорткод форми в контенті | ✅ працює | ❌ складнощі | ✅ працює |
Якщо форма живе на одній сторінці в окремому шаблоні, беріть спосіб 2 (офіційний метод). Якщо сайт на сучасному бандлері й форм може бути кілька в різних місцях, спосіб 3 (lazy-cf7-assets). Якщо потрібне рішення «прямо зараз» без правлення шаблонів, спосіб 1 (defer), але пам'ятайте про ліміти.
Один важливий нюанс: після будь-якої з цих змін обов'язково перевірте, що форма відправляється, валідація працює, reCAPTCHA не зламалася, а стилі не попливли. Відкрийте сторінку з формою в інкогніто, заповніть і відправте тестове повідомлення до та після.
⁉️🤔 Часті запитання
Чому CF7 взагалі завантажує скрипти на всіх сторінках?
Плагін не знає на етапі завантаження WordPress, чи є на конкретній сторінці шорткод форми. WordPress збирає сторінку пізніше, коли черга скриптів уже сформована. Розробник Takayuki Miyoshi пояснює це в офіційній документації: технічно неможливо визначити наявність шорткоду до хука
wp_head. Тому обрано консервативний підхід, завантажувати завжди. Це свідоме архітектурне рішення, а не баг: плагін жертвує продуктивністю заради гарантованої працездатності. Тягар оптимізації переноситься на розробника сайту.
Чи зламається форма після вимкнення глобального завантаження?
Ні, якщо акуратно увімкнути скрипти назад на потрібних сторінках. Форма втратить AJAX-надсилання та клієнтську валідацію лише на тих сторінках, де скрипти не підключені. Тому крок 2 (повернення скриптів) обов’язковий, не зупиняйтеся на самому лише
WPCF7_LOAD_JS = false. Перевірте порядок викликів:wpcf7_enqueue_scripts()має йти доwp_head(), а не після. І переконайтеся, що reCAPTCHA не конфліктує з defer-завантаженням.
Чи працює метод із константами в CF7 6.x?
Так, константи
WPCF7_LOAD_JSіWPCF7_LOAD_CSSповністю підтримуються в актуальній версії 6.1.6 (див. офіційний лог версій). За всю історію плагіна, з версії 3.9 до поточної 6.x, ці константи жодного разу не оголошувалися застарілими. Це найстабільніший і задокументований спосіб керування завантаженням.
Що робити, якщо форм кілька і вони в різних місцях?
Якщо форми розкидані по різних сторінках через шорткоди в контенті (а не в шаблонах), офіційний метод із шаблонами незручний. Використовуйте або
lazy-cf7-assets(спосіб 3), або плагін Conditionally Load CF7: він додає в адмінку налаштування, на яких сторінках/post types вмикати скрипти, і працює без правлення коду.
Три рядки коду проти десятка запитів
Проблема «CF7 завантажує скрипти всюди» існує рівно стільки ж, скільки сам плагін, і за 10+ років розробник не змінив поведінку за замовчуванням, тому що це компроміс між простотою та продуктивністю. Але компроміс — це не вирок.
Найбезпечніший шлях, офіційний метод із константами та шаблонами. Він прибирає скрипти та стилі плагіна з усіх сторінок, крім тих, де вони потрібні, і не ламається під час оновлень. Якщо сайт на сучасному стеку з бандлером, придивіться до lazy-cf7-assets. Якщо потрібно швидко і без правлення шаблонів, defer через хук clean_url дасть приріст до метрик уже сьогодні.
Перевірте свій сайт через PageSpeed Insights до і після, зниження кількості блокувальних запитів на 1-2 одиниці та економія 10-30 КБ на сторінку можуть підняти показник Performance на 2-5 балів, особливо на мобільних пристроях.



