Вопрос или проблема
Я откладываю скрипты JS, чтобы оптимизировать время загрузки страницы и SEO. Мой код для откладывания скриптов выглядит примерно так:
add_filter(
'script_loader_tag', // Фильтрует HTML-тег скрипта добавленного в очередь.
function ( $tag, $handle ) {
return str_replace( ' src', ' defer="defer" src', $tag );
}
);
Это работает нормально для большинства скриптов. Однако, когда он откладывает скрипты, такие как wp-i18n
, это вызывает ошибку из-за кода -js-after
, который он пытается выполнить перед выполнением откладываемого скрипта.
<script type="text/javascript" defer="defer" src="http://192.168.1.71/wp-includes/js/dist/i18n.min.js?ver=db9a9a37da262883343e941c3731bc67" id='wp-i18n-js'></script>
<script type="text/javascript" id='wp-i18n-js-after'>
wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } );
</script>
Проблема в том, что скрипт откладывается в отличие от его скрипта -js-after
. Мне нужно решение, которое делает одно из следующего.
- Пропускает откладывание скриптов, которые имеют
-js-after
- Откладывает
js-after
вместе со скриптом.
Реализация первого варианта с использованием
$data = $wp_scripts->get_data( 'wp-i18n', 'data' );
не работает, потому что $data не содержит информации о том, имеет ли скрипт -js-after
. Поиск “обнаружение ‘WordPress -js-after'” не дает никаких полезных результатов.
Необходимо исключить добавление defer для файлов, которые имеют -js-after
. В моем случае ошибка была вызвана файлами hooks.min.js
и i18n.min.js
.
Эта функция отлично сработала в моем случае:
function defer_parsing_of_js( $url ) {
if ( is_user_logged_in() ) return $url; //не ломать WP Admin
if ( FALSE === strpos( $url, '.js' ) ) return $url;
if ( strpos( $url, "jquery.min.js" ) || strpos( $url, "jquery-migrate.min.js" ) || strpos( $url, "hooks.min.js" ) || strpos( $url, "i18n.min.js" )) {
return $url;
}
return str_replace( ' src', ' defer src', $url );
}
add_filter( 'script_loader_tag', 'defer_parsing_of_js', 10 );
Ответ или решение
В качестве ИТ-эксперта, рассмотрим проблему, связанную с добавлением атрибута defer
к скрипту wp-i18n
, которая приводит к ошибке консоли с сообщением «wp is not defined» в forms Gravity. Рассмотрим, как можно решить эту проблему, избегая разбросанных шаблонов и клише.
Проблема
При оптимизации времени загрузки страницы и SEO, вы используете фильтр script_loader_tag
для добавления атрибута defer
к загружаемым скриптам. Однако, это приводит к проблеме, когда скрипты с суффиксом -js-after
пытаются выполниться до того, как основной скрипт был загружен и выполнен. В результате возникает ошибка, указывающая на то, что объект wp
не определен.
add_filter(
'script_loader_tag',
function ( $tag, $handle ) {
return str_replace( ' src', ' defer="defer" src', $tag );
}
);
Это решение неплохо работает, однако приводит к ошибкам, когда попытки доступа к объекту wp
происходят, прежде чем скрипт wp-i18n
завершит загрузку.
Решение
Для устранения описанной проблемы предлагаю два подхода.
1. Исключение деферы для скриптов с суффиксом -js-after
Первый предложенный вариант — пропустить добавление атрибута defer
для скриптов, имеющих суффикс -js-after
. Можно проверить имя загружаемого скрипта и, в случае совпадения, вернуть оригинальный тег без изменений. Это достигается следующим образом:
function defer_parsing_of_js( $url ) {
if ( is_user_logged_in() ) return $url; // Не нарушаем работу в админке WP
if ( FALSE === strpos( $url, '.js' ) ) return $url;
// Проверяем, является ли скрипт -js-after
if ( strpos( $url, '-js-after' ) !== false ) {
return $url; // Игнорируем скрипт с -js-after
}
return str_replace( ' src', ' defer src', $url );
}
add_filter( 'script_loader_tag', 'defer_parsing_of_js', 10 );
Этот код проверяет, есть ли в имени файла суффикс -js-after
, и если да, то не добавляет атрибут defer
.
2. Деферирование как основного, так и вспомогательного скрипта
Второй вариант, который можно рассмотреть, заключается в том, чтобы сделать так, чтобы скрипты с суффиксом -js-after
тоже обрабатывались с атрибутом defer
. Для этого нужно добавить дополнительные действия для их правильной обработки. Рассмотрим как это можно сделать:
add_filter( 'script_loader_tag', 'defer_parsing_of_js', 10 );
function defer_parsing_of_js( $tag, $handle ) {
if ( is_user_logged_in() ) return $tag; // Не влезаем в админку
if ( strpos( $handle, '-js-after' ) !== false || strpos( $url, 'hooks.min.js' ) !== false || strpos( $url, 'i18n.min.js' ) !== false ) {
return $tag; // Игнорируем скрипты, требующие предшествующей загрузки
}
return str_replace( ' src', ' defer src', $tag );
}
Выводы
В зависимости от ваших нужд, вы имеете два решения: исключить гипертекстовую ферму для определенных скриптов или использовать подход с добавлением атрибута defer
ко всем скриптам, включая вспомогательные.
Эти методы не только помогут устранить ошибку, но и позволят поддерживать оптимизацию загрузки вашей страницы, что крайне важно для улучшения SEO-показателей и общего пользовательского опыта.