reCAPTCHA в MODX без лишних запросов: как приручить простыню из скриптов

Коротко. На странице было много форм AjaxForm, каждая тянула https://www.google.com/recaptcha/api.js и рендерила свой виджет reCAPTCHA v2. Это приводило к «лавине» сетевых запросов (anchor, frame, webworker.js, recaptcha__*.js), просадке производительности и багам при валидации. Мы оставили единый загрузчик скрипта и включили ленивую отрисовку виджетов: капча рисуется только когда блок попадает во вьюпорт или появляется в модалке. Результат — резкое сокращение фоновых загрузок без ломки верстки и MODX-чанков.

Проблема

Сценарий знакомый: на посадочной странице несколько форм, каждая добавляет контейнер <div class="g-recaptcha"> и тут же вставляет <script src="https://www.google.com/recaptcha/api.js?hl=ru">. В результате:

Почему так происходит

reCAPTCHA v2 устроена так, что каждый отдельный виджет — это не просто один DOM-элемент, а связка из нескольких ресурсов. Когда на странице 5–10 форм, умножаем эту связку на количество виджетов — вот и «шум» в сети. А если скрипт api.js подключен несколько раз, проблемы множатся: дубли инициализации, гонки, пустой g-recaptcha-response на бэкенде.

Альтернативы и что выбрать

 

 

Нюансы, о которых легко забыть

Решение: ленивый рендер reCAPTCHA v2 в MODX

Я добился того, что скрипт грузится один раз, а сами виджеты рендерятся только тогда, когда они действительно нужны (в зоне видимости или при открытии модалки). Для этого достаточно двух компонентов:

1) Чанк reCAPTCHA

<div class="g-recaptcha" data-sitekey=""></div>

Важно: никакого <script src=".../api.js"> в этом чанке быть не должно.

2) Сниппет recaptchav2_lazy_loader

Сниппет подключает api.js один раз с render=explicit и бережно, а также включает ленивую отрисовку всех .g-recaptcha по мере видимости и появления. В шаблоне достаточно вставить:

Что делает сниппет

Пошаговый чек-лист внедрения

  1. В чанке reCAPTCHA оставить только <div class="g-recaptcha"> с корректным data-sitekey.
  2. В шаблон добавить вызов (один раз на страницу).
  3. Очистить кэш MODX, сделать «жёсткую» перезагрузку.
  4. Проверить в DevTools - Network - фильтр recaptcha:

Как быть, если нужна ещё меньшая нагрузка

FAQ

Почему в HAR всё равно видно несколько webworker.js и anchor?
Потому что для каждого реально отрисованного виджета reCAPTCHA v2 это норма. Мы убираем лишнюю одновременную инициализацию и дубли, но не меняем архитектуру v2 checkbox. Зато теперь виджеты рисуются только по мере нужды — и стартовая «лавина» исчезает.

Нужно ли вешать загрузку на события (клик/idle)?
Нет, если виджеты только ниже по странице и рендерятся через IntersectionObserver. Для скрытых модалок полезно добавить хук «по открытию» (рендерить внутри модалки в момент показа).

Что если другой виджет сам тянет reCAPTCHA?
«Умный» лоадер просто не подгрузит скрипт второй раз. Если сторонний код рендерит свои виджеты — они появятся только когда контейнер станет видимым (у нас это также покрыто наблюдателем DOM).

Итог

Я сохранил текущий стек (MODX + AjaxForm + reCAPTCHA v2) и убрал главную причину перегрузки: многократную инициализацию и ранний рендер всех виджетов сразу. Теперь reCAPTCHA подстраивается под реальное поведение пользователя: грузим один скрипт — рисуем только то, что нужно, тогда, когда нужно.