Примеры блокирующих и неблокирующих ресурсов при загрузке страницы
Что проверяют
Знаете ли вы, что именно тормозит браузер на пути от первого байта до первой отрисовки, и умеете ли это чинить. Вопрос практический: по ответу видно, разбирали ли вы реальную медленную страницу или читали про оптимизацию.
Как отвечать
Разделите два разных блокирования: разбора разметки и отрисовки.
Парсер останавливает обычный <script src="..."> без атрибутов: пока файл не скачан и не выполнен, DOM дальше не строится. Встроенный скрипт блокирует так же и вдобавок ждёт объявленные выше стили, потому что может их читать.
Отрисовку блокирует таблица стилей: пока CSS не загружен, браузер не показывает содержимое, чтобы не мигать нестилизованным текстом.
Не блокируют: скрипты с async и defer, изображения, шрифты, предзагрузка через preload, а также стили, ограниченные атрибутом media, например для печати.
Разницу между атрибутами проговорите отдельно: async качается параллельно и выполняется сразу по готовности, прерывая разбор, порядок между такими скриптами не гарантирован. defer тоже качается параллельно, но выполняется после построения DOM и в порядке объявления. Модули отложены по умолчанию.
Отсюда рецепты: аналитике и виджетам async, своему коду defer, критичный CSS встроить, остальное вынести, шрифтам font-display: swap, картинкам вне экрана loading="lazy", а главной картинке первого экрана наоборот повышенный приоритет.
Где спотыкаются
Ставят async всему подряд. Скрипт, который зависит от DOM или от соседнего файла, выполняется раньше, чем должен, и падает через раз, причём на быстрой машине разработчика это почти не ловится.
Второе: думают, что шрифт задерживает всю страницу. Он задерживает только текст, которому назначен, и поведение определяется font-display: по умолчанию такой текст какое-то время просто невидим.
Третье: путают defer и скрипт в конце <body>. Второй действительно не мешает разметке, но браузер узнаёт о файле поздно и начинает качать его позже, тогда как defer качает параллельно разбору.