Разница между async и defer в теге 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, улучшая производительность ваших страниц.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *