Справжня відповідь така: Тому що ви не можете довіряти відкладенню.
Поняття відкладення та асинхронізація відрізняються наступним чином:
async дозволяє завантажувати сценарій у фоновому режимі без блокування. Потім, коли закінчується завантаження, візуалізація блокується, і цей сценарій виконується. Візуалізація поновлюється після виконання сценарію.
defer робить те ж саме, за винятком претензій, які гарантують виконання сценаріїв у тому порядку, який вони були вказані на сторінці, і що вони будуть виконані після завершення розбору документа. Отже, деякі сценарії можуть закінчити завантаження, потім сидіти і чекати скриптів, які завантажувались пізніше, але з'являлися перед ними.
На жаль, через те, що насправді є стандартом боротьби з котами, визначення відстрочки змінюється специфікацією до специфікації, і навіть в останніх специфікаціях не дає корисної гарантії. Як показують відповіді тут і це питання , браузери реалізують відкладати інакше:
- У певних ситуаціях у деяких браузерах є помилка, яка спричиняє
defer
невдачу сценаріїв.
- Деякі браузери затримують
DOMContentLoaded
подію до моменту завантаження defer
сценаріїв, а деякі не.
- Деякі браузери підкоряються
defer
на <script>
елементах з інлайн кодом і без src
атрибута, і деякі його ігнорувати.
На щастя, специфікація принаймні вказує, що асинхронізація перевизначає відкладати. Таким чином, ви можете ставитися до всіх сценаріїв як до асинхронізованих та отримувати широкий спектр підтримки браузера так:
<script defer async src="..."></script>
98% браузерів, які використовуються у всьому світі та 99% у США, уникатимуть блокування при такому підході.
(Якщо вам потрібно зачекати, поки документ закінчить розбір, прослухайте подію DOMContentLoaded
події або скористайтеся зручною .ready()
функцією jQuery . Ви все одно хочете зробити це, щоб витончено повернутися до браузерів, які взагалі не реалізують defer
.)