
Асинхронная и отложенная загрузка 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";
Но, такой код не всегда давал значительный прирост, да и мог порушить структуру сайта.

Я решил задачку усложнить, чтобы более точно управлять отложенной и асинхронной загрузкой в 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);
Располагаться они могут практически в любом файле, который запускает загрузку скриптов. На скриншоте показываю наглядно, что вам нужно найти.
Ничего сложно, кроме того, что на каждый скрипт пилить такую структуру трудоемко, потому, сделаем код более массовым.
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

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

