Різниця між async та defer у тега script
Скрипти, що підключаються (JavaScript) блокує завантаження HTML коду. Коли браузер (парсер) доходить до тега <script> , він зупиняється, щоб завантажити контент файлу і виконати його код, і тільки після цього продовжує парсинг HTML.
Така поведінка може гальмувати відображення HTML, коли на сторінці завантажується багато JavaScript. Часто код цих файлів не потрібен, щоб показати сторінки HTML. Саме тому рекомендується підключати скрипти наприкінці сторінки. Однак цю рекомендацію не завжди можна дотриматись і для таких випадків є інші способи не блокувати малювання HTML.
Елемент <script> має два атрибути, async і defer , які можуть дати нам більше контролю над тим, як і коли файл завантажуються і виконуються.
Звичайне виконання
<html> <head> ... </head> <body> ... <script src="script.js"> .... </body> </html>
Атрибут async
Означає, що скрипт є абсолютно незалежним:
- Сторінка не чекає асинхронних скриптів, вміст обробляється та відображається.
- Подія
DOMContentLoaded
та асинхронні скрипти не чекають один на одного:- DOMContentLoaded може статися як до асинхронного скрипта (якщо асинхронний скрипт завершить завантаження після того, як сторінка буде готова),
- …так і після асинхронного скрипта (якщо він короткий або міститься в HTTP-кеші).
- Інші скрипти не чекають async, і скрипти c async не чекають інші скрипти.
<script async src="script.js">
Атрибут defer
Повідомляє браузеру, що він повинен продовжувати обробляти сторінку і завантажувати скрипт у фоновому режимі, а потім запустити цей скрипт, коли дерево DOM буде повністю побудовано.
- Скрипти з defer ніколи не блокують сторінку.
- Скрипти з defer завжди виконуються, коли дерево DOM готове, але до події
DOMContentLoaded
.
<script defer src="script.js">
Де та що використовувати?
Залежить від ситуації. Розглянемо кілька запитань щодо цієї теми.
Де знаходиться елемент <script> ?
Якщо файл JavaScript знаходиться безпосередньо перед тегом, що закриває </body> , використовувати async або defer не має сенсу оскільки до цього моменту парсер вже проаналізував весь HTML код.
Чи є скрипт самодостатнім?
Для файлів (скриптів), які не потрібні для роботи інших скриптів і не мають залежностей від інших скриптів, атрибут async особливо корисний. Оскільки в цьому випадку байдуже, в який саме момент виконується скрипт, асинхронне завантаження є найбільш підходящим варіантом.
Чи потрібний повністю завантажений DOM для роботи скрипта?
Якщо це необхідно, то використання async доречно тільки якщо скрипт розрахований на асинхронне завантаження – тобто. він чекає на події поки завантажитися DOM і тільки потім починає свою роботу.
Або можна використовувати атрибут defer . У цьому випадку розміщувати виклик script можна будь-де HTML.
Чи маленький скрипт?
Якщо скрипт відносно малий і від нього залежать або залежить від інших скриптів, то його можна вбудувати прямо в HTML (підключити inline).
Підтримка браузерами
Підтримка async – {%}
Підтримка defer – {%}
Додавання атрибутів defer або async у WordPress
Штатних способів зробити це немає, тому будемо користуватися хуком script_loader_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; } }