Skip to content

Всё для WordPress, веб-разработки — и не только

⚡ Contact Form 7 — отложенная загрузка скриптов и стилей для ускорения WordPress

⚡ 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, безопаснее при обновлениях):

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}

Функция проверяет URL каждого подключаемого скрипта через хук clean_url. Если в адресе есть contact-form-7 и расширение .js, добавляет defer='defer'. Все остальные скрипты не трогает.

Плюс: решение в 10 строк, не требует правки шаблонов или конфигурации плагина. Подходит для тем, где нет отдельного шаблона страницы контактов.

Минус: скрипт всё ещё загружается на каждой странице, вы просто убираете блокировку рендеринга. Трафик и запросы к серверу не сокращаются. CSS плагина этот метод вообще не затрагивает, таблица стилей грузится как обычно.

Способ 2: официальный метод, условная загрузка через константы

Этот подход описан в документации Contact Form 7 самим разработчиком плагина, Такаюки Миёси. Идея в два шага: сначала глобально отключаем скрипты и стили CF7, затем включаем их обратно, но только на тех страницах, где форма реально используется.

Шаг 1: отключить загрузку на всех страницах

Добавьте в wp-config.php две константы:

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

Альтернативно, через functions.php темы:

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

После этого CF7 не будет грузить ни строчки своего кода ни на одной странице сайта, включая те, где форма есть. Форма без скриптов теряет AJAX-отправку и валидацию, поэтому нужен шаг 2.

Шаг 2: вернуть скрипты на страницы с формой

Предположим, у вас страница контактов использует шаблон page-contact.php в папке темы. Добавьте в этот шаблон до вызова 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}

Функции 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 и только после этого динамически подгружает скрипты плагина.

Установка:

1npm install lazy-cf7-assets

Перед использованием нужно отключить автоматическую загрузку JS плагина (как в способе 2, через wpcf7_load_js):

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

Затем в вашем JS-бандле:

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

Если скрипты грузятся в <head>, а не в конце <body>, укажите абсолютный путь к загрузочной GIF-картинке, чтобы форма не «мигала» пустым состоянием:

1lazyform.init({
2 gifPath: '/wp-content/themes/my-theme/images/ajax-loader.gif'
3});
Скриншот репозитория lazy-cf7-assets на GitHub

Плюс: 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 баллов, особенно на мобильных устройствах.