Разница между атрибутами async и defer в теге
Когда вы добавляете скрипты (JavaScript) на страницу, они могут блокировать загрузку HTML-кода. Это происходит так: когда браузер встречает тег <script>, он останавливает загрузку страницы, загружает файл скрипта и выполняет его код, а затем продолжает обработку HTML.
Такое поведение может замедлить отображение страницы, особенно если на ней много JavaScript-файлов. Часто код этих файлов не требуется для первоначального отображения HTML. Поэтому рекомендуется добавлять скрипты в конце страницы. Однако это не всегда возможно, и в таких случаях существуют альтернативы, чтобы не блокировать рендеринг HTML.
Тег <script> имеет два атрибута: async и defer, которые позволяют лучше контролировать, как и когда загружаются и выполняются файлы.
Обычное выполнение
...
...
Атрибут defer
Атрибут defer указывает браузеру продолжать обрабатывать страницу и загружать скрипт в фоновом режиме. Скрипт будет выполнен, когда структура документа (DOM) будет полностью готова.
- Скрипты с
deferникогда не блокируют страницу. - Скрипты с
deferвыполняются, когда DOM готов, но до событияDOMContentLoaded.
Когда и что использовать?
Выбор между async и defer зависит от ситуации. Рассмотрим несколько вопросов на эту тему.
Где расположен элемент <script>?
Если файл JavaScript находится сразу перед закрывающим тегом </body>, использовать async или defer не имеет смысла, так как к этому моменту браузер уже проанализировал весь HTML-код.
Содержит ли скрипт зависимость от других скриптов?
Если файл (скрипт) не зависит от других скриптов, атрибут async подходит особенно хорошо. В таком случае не важно, когда именно скрипт будет выполнен, и асинхронная загрузка — это лучший выбор.
Нуже�� ли полностью загруженный DOM для работы скрипта?
Если для работы скрипта необходим загруженный DOM, то использование async целесообразно только в том случае, если скрипт предназначен для асинхронной загрузки — то есть он ожидает загрузки DOM и только тогда начинает свое выполнение.
В этом случае можно использовать атрибут defer, позволяющий разместить вызов скрипта в любом месте HTML.
Скрипт маленький?
Если скрипт относительно небольшой и зависит от других скриптов или на него зависят другие скрипты, его можно встроить непосредственно в HTML (inline).
Поддержка браузерами
Поддержка async — {percent}
Поддержка defer — {percent}
Добавление атрибутов defer или async в WordPress
С версии WP 6.3
В WP 6.3 добавлена поддержка регистрации скриптов с атрибутами async и defer.
Пример: отложенная загрузка скрипта в заголовке
wp_register_script(
'my_script',
'https://example.com/path/to/my_script.js',
[],
'1.0',
[
'strategy' => 'defer'
]
);
Пример: асинхронная загрузка скрипта внизу страницы
wp_register_script(
'my_script',
'https://example.com/path/to/my_script.js',
[],
'1.0',
[
'in_footer' => true,
'strategy' => 'async',
]
);
Точно так же работает функция wp_enqueue_script().
Пример: использование wp_script_add_data()
Загрузку можно также настроить с помощью wp_script_add_data(). Это может быть полезно, когда нужно поддерживать более ранние версии WP.
wp_register_script(
'my_script',
'https://example.com/path/to/my_script.js',
[],
'1.0.0',
false
);
wp_script_add_data('my_script', 'strategy', 'defer');
До версии WP 6.3
Ранее не существовало встроенных способов сделать это, поэтому мы будем использовать хук script_loader_tag.
add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' );
add_filter( 'script_loader_tag', 'my_script_loader_tag', 10, 2 );
function my_enqueue_scripts() {
wp_enqueue_script( 'app', get_template_directory_uri() . 'js/app.js' );
// Добавляем атрибут async к зарегистрированному скрипту.
wp_script_add_data( 'app', 'async', true );
}
function my_script_loader_tag( $tag, $handle ) {
foreach ( ['async', 'defer'] as $attr ) {
if (!wp_scripts()->get_data($handle, $attr)) {
continue;
}
// Предотвращаем добавление атрибута дважды.
if (!preg_match("~s{$attr}[=>s]~", $tag)) {
$tag = preg_replace('~(?=>)~', " $attr", $tag, 1);
}
break; // Только async или defer, не оба.
}
return $tag;
}
Упрощенная версия
add_action( 'wp_enqueue_scripts', 'my_scripts_method' );
function my_scripts_method(){
// Подключаем скрипт
wp_enqueue_script( 'my-script', get_template_directory_uri() . '/js/my-script.js' );
// Добавляем атрибут defer к скрипту с id my-script
add_filter( 'script_loader_tag', 'change_my_script', 10, 3 );
function change_my_script( $tag, $handle, $src ){
if( 'my-script' === $handle ){
// return str_replace( ' src', ' async src', $tag );
return str_replace( ' src', ' defer src', $tag );
}
return $tag;
}
}
Таким образом, вы можете эффективно управлять загрузкой ваших скриптов в WordPress, улучшая производительность ваших страниц.