В чем разница стратегий загрузки скриптов async и defer в HTML
Что проверяют
Понимаете ли вы, что оба не блокируют разбор HTML, и знаете ли разницу в моменте выполнения и порядке.
Как отвечать
Без атрибутов браузер, встретив <script src>, останавливает разбор HTML, загружает файл и выполняет его. Отсюда правило класть скрипты в конец body.
async: файл загружается параллельно разбору, но выполняется сразу по готовности, прерывая разбор. Порядок выполнения не гарантирован: кто раньше загрузился, тот раньше и выполнился.
defer: файл тоже загружается параллельно, но выполняется после полного разбора документа, перед событием DOMContentLoaded. Порядок сохраняется, скрипты выполнятся в том же порядке, в каком объявлены.
Как выбирать: defer для кода приложения, который зависит от DOM и от других скриптов; async для независимых сторонних скриптов вроде аналитики, которым всё равно, когда выполниться и в каком порядке.
Важные детали: оба атрибута действуют только на скрипты с src, для встроенного кода они игнорируются. У type="module" поведение defer по умолчанию, а async для него тоже допустим.
Полезно связать с загрузкой страницы: скрипт без атрибутов в head это классическая причина плохого показателя первой отрисовки, потому что разбор HTML стоит на месте, пока файл едет по сети.
Где спотыкаются
Считают, что async и defer откладывают загрузку, а не выполнение.
Ставят async на скрипты с зависимостями и получают плавающие ошибки.
Пишут defer на встроенный скрипт и ждут отложенного выполнения.
Не знают, что модули по умолчанию ведут себя как defer.