Drupal → Дружим reCAPTCHA v3 и PageSpeed

04.10.2023

Способ скрыть от PageSpeed наличие reCaptcha v3, которая сильно портит результаты для мобильных устройств. Способ основан на отложенной загрузке внешних js файлов рекапчи.

MODULENAME.module:

/**
 * Implements hook_library_info_alter().
 */
function MODULENAME_library_info_alter(array &$libraries, string $extension): void {
  if ($extension == 'recaptcha_v3') {
    foreach ($libraries['google.recaptcha']['js'] as $file_name => $file_info) {
      if (
        str_starts_with($file_name, 'https://www.google.com/recaptcha/api.js') ||
        str_starts_with($file_name, 'https://www.recaptcha.net/recaptcha/api.js')
      ) {
        $libraries['google.recaptcha']['js'][$file_name]['attributes']['timeout'] = 4000;
      }
    }
  }
}

/**
 * Implements hook_element_info_alter().
 */
function MODULENAME_element_info_alter(array &$info): void {
  array_unshift($info['html_tag']['#pre_render'], '\Drupal\MODULENAME\TrustedCallbacks::htmlTagPreRender');
}

src/TrustedCallbacks.php:

<?php

namespace Drupal\MODULENAME;

use Drupal\Core\Security\TrustedCallbackInterface;

class TrustedCallbacks implements TrustedCallbackInterface {

  /**
   * {@inheritDoc}
   */
  public static function trustedCallbacks(): array {
    return ['htmlTagPreRender'];
  }

  /**
   * #pre_render callback for "html_tag" element.
   */
  public static function htmlTagPreRender(array $element): array {
    if ($element['#tag'] == 'script' && !empty($element['#attributes']['timeout'])) {
      $element['#value'] = <<<JS
        setTimeout(function () {
          const script = document.createElement('script');
          script.src = '{$element['#attributes']['src']}';
          script.async = true;
          document.getElementsByTagName('head')[0].appendChild(script);
        }, {$element['#attributes']['timeout']});
      JS;
      unset($element['#attributes']);
    }

    return $element;
  }

}

До:

После:

Код доступен в виде модуля.

Написанное актуально для
Drupal 8+
Похожие записи

Добавить комментарий