Установка WordPress на хостинг
WordPress

Асинхронная и отложенная загрузка js в WordPress

Поделитесь с друзьями:

С версии 4.1 был добавлен отличный фильтр — script_loader_tag. Теперь нет необходимости извергать пламя из не предназначенных для того мест при добавление к скриптам атрибутов async или defer. Все делается довольно просто.

P. S. весь предложенный ниже код подключать требуется через файл functions.php, желательно, в рамках дочерней темы. Также можно вынести в собственный плагин.

В самом начале я старался использовать что-нибудь универсальное, чтобы не было проблем, например, это:

function wcs_defer_javascripts ( $url ) {
    if(is_admin()) return $url;
    if ( FALSE === strpos( $url, '.js' ) ) return $url;
    if ( strpos( $url, 'jquery.js') ) return $url;
    return "$url' defer='defer";
}
add_filter( 'clean_url', 'wcs_defer_javascripts', 11, 1 );

Для запуска асинхронной загрузки достаточно поменять строку:

return "$url' defer='defer";

на:

return "$url' async='async";

Но, такой код не всегда давал значительный прирост, да и мог порушить структуру сайта.

async слайдер
Пример разрушенного асинхронной загрузкой скриптов слайдера

Я решил задачку усложнить, чтобы более точно управлять отложенной и асинхронной загрузкой в WordPress и нашел такое решение:

function add_async_forscript($url)
{
    if (strpos($url, '#asyncload')===false)
        return $url;
    else if (is_admin())
        return str_replace('#asyncload', '', $url);
    else
        return str_replace('#asyncload', '', $url)."' async='async"; 
}
add_filter('clean_url', 'add_async_forscript', 11, 1);

Теперь к любому скрипту можно просто добавить #asyncload, чтобы присвоить атрибут async. Пример ниже:

wp_enqueue_script('myscriptass', 'assest/js/myscriptass.js#asyncload' );

Таким образом требуется подключать скрипты в файле functions.php.

Для отложенной загрузки создавал аналогичный код с атрибутами defer. Все довольно просто. Но есть более правильное решение, о котором расскажу дальше. И появилось оно вместе с выпуском WP 4.1 и добавлением нового фильтра.

apply_filters('script_loader_tag', string $tag, string $handle, string $src);
//виновник торжества

Собственно, это нужный фильтр. Просто для примера, его вставлять никуда не требуется.

Теперь переходим непосредственно к добавлению асинхронной загрузки на отдельный скрипт:

function add_async_attribute($tag, $handle) {
    if ( 'my-js-handle' !== $handle )
        return $tag;
    return str_replace( ' src', ' async="async" src', $tag );
}
add_filter('script_loader_tag', 'add_async_attribute', 10, 2);

Если необходимо добавить отложенную загрузку, то код будет выглядеть так:

function add_defer_attribute($tag, $handle) {
    if ( 'my-js-handle' !== $handle )
        return $tag;
    return str_replace( ' src', ' defer="defer" src', $tag );
}
add_filter('script_loader_tag', 'add_defer_attribute', 10, 2);

Как видите, просто заменили async на defer.

Наверное, содержание вызвало вопрос. Итак, все довольно просто. Данная функция проверяет скрипт на соответствие. Если js не соответствует параметру $handle, то возвращает атрибут по умолчанию, если же соответствует, то присваивает нужный атрибут. Наверное, возник вопрос, где найти значение $handle?

В таких строках:

wp_register_script('my-js-handle', $src, $deps, $ver, $in_footer);

или:

wp_enqueue_script('my-js-handle', $src, $deps, $ver, $in_footer);

Располагаться они могут практически в любом файле, который запускает загрузку скриптов. На скриншоте показываю наглядно, что вам нужно найти.

Асинхронная и отложенная загрузка js

Ничего сложно, кроме того, что на каждый скрипт пилить такую структуру трудоемко, потому, сделаем код более массовым.

function add_defer_attribute($tag, $handle) {
   // добавляем дескрипторы в массив
   $scripts_to_defer = array('my-js-handle', 'another-handle'); //здесь размещаем те самые $handle

   foreach($scripts_to_defer as $defer_script) {
      if ($defer_script === $handle) {
         return str_replace(' src', ' defer="defer" src', $tag);
      }
   }
   return $tag;
}
add_filter ('script_loader_tag', 'add_defer_attribute', 10, 2);

Отличие кода только в том, что на соответствие проверяются все значения массива. И если соответствие найдено, то будет присвоен атрибут defer. Для асинхронной загрузки код отдельный.

function add_async_attribute($tag, $handle) {
   // добавляем дескрипторы в массив
   $scripts_to_async = array('my-js-handle', 'another-handle'); //здесь размещаем те самые $handle

   foreach($scripts_to_async as $async_script) {
      if ($async_script === $handle) {
         return str_replace(' src', ' async="async" src', $tag);
      }
   }
   return $tag;
}
add_filter ('script_loader_tag', 'add_async_attribute', 10, 2);

Чем хорош данный вариант? Можно с легкостью разбить часть скриптов на отложенные, другую на асинхронные, избежав конфликтов. Но для этого придется понимать, как и в какой последовательности работают скрипты на сайте.

Надеюсь, сумел вам помочь, задача нелегкая, но, как видите, решаемая.

Асинхронная и отложенная загрузка js в WordPress
Асинхронная и отложенная загрузка js в WordPress 1

С версии 4.1 был добавлен отличный фильтр — script_loader_tag. Теперь нет необходимости извергать пламя из не предназначенных для того мест при добавление

Рейтинг редакторов:
0

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

Ваш e-mail не будет опубликован.