Total Blocking Time (TBT): как снизить
TBT — суммарное время, когда страница не отвечает на клик и ввод. Снижают метрику, разбивая длинный JavaScript и откладывая чужие виджеты.
Total Blocking Time (TBT) — это суммарное время, когда страница уже начала показываться, но не отвечает на действия. Клик, прокрутка и ввод в это окно ждут, пока главный поток браузера доделает длинную работу. В Lighthouse и PageSpeed Insights хороший TBT — до 200 миллисекунд. От 200 до 600 миллисекунд метрика средняя, дольше 600 — слабая.
Счёт идёт в лабораторном замере, между первой отрисовкой контента и моментом, когда страница становится интерактивной. В полевых данных ту же отзывчивость показывает INP: это показатель Core Web Vitals, который описывает задержку ответа на действие. TBT сам по себе в Core Web Vitals не входит, но по нему видно проблему ещё до того, как накопится статистика визитов. Снизить TBT — практический способ заранее улучшить INP.
Метрика не про то, как быстро появилась картинка. Пока документ едет с сервера, TBT ещё не считается. Он начинается после первой отрисовки. Первую отрисовку разбирает материал First Contentful Paint (FCP): как ускорить. Общий разбор скорости — в статье как ускорить загрузку сайта.
Как устроена блокировка
Браузер выполняет JavaScript, считает стили и раскладывает блоки в одном потоке. Пока задача короче 50 миллисекунд, вкладка успевает ответить на жест. Всё, что длится дольше, называют длинной задачей. В TBT попадает не вся её длина, а только хвост сверх 50 миллисекунд. Задача на 240 миллисекунд добавляет 190. Десять таких задач дают почти две секунды блокировки, хотя по отдельности они кажутся короткими.
Пока идёт длинная задача, браузер не обрабатывает клик. Кнопка нажимается с опозданием, меню открывается рывком, поле ввода принимает буквы пачкой. Для человека это и есть «сайт тормозит», хотя текст и картинка на экране уже есть.
Откуда берётся высокий TBT
- 01Свой скрипт выполняется целиком при открытии: каталог, корзина, фильтры и чужие блоки лежат в одном файле.
- 02Чат, метрика, пиксели, карты и виджеты стартуют сразу и занимают поток раньше, чем человек успел нажать.
- 03Гидратация. HTML уже виден, но фреймворк заново собирает страницу в браузере и на это время глушит ввод.
- 04Долгий цикл без пауз: перебор большого списка, пересчёт фильтра, разбор тяжёлого JSON.
- 05Диспетчер тегов тянет цепочку скриптов. Каждый следующий тоже попадает в сумму.
- 06Принудительный пересчёт вёрстки: скрипт читает размер блока и тут же меняет стиль, браузер перекладывает страницу на каждом шаге.
Как снизить TBT
Цель одна: когда человек хочет нажать, в главном потоке не должно быть задачи длиннее 50 миллисекунд. Ниже — что сделать по шагам.
1. Отложите чужие скрипты. Чат, онлайн-консультант, карта, виджет отзывов, пиксель рекламы и лишняя метрика не нужны в первую секунду. Их подключают после загрузки страницы или по первому действию: открытие чата, доскролл до карты. В диспетчере тегов убирают срабатывания, которые висят на всех страницах сразу. Атрибуты async и defer только переносят момент запуска. Если скрипт всё равно выполняется до клика, он по-прежнему входит в TBT.
2. Разделите свой код. На открытую страницу попадает только то, без чего не работают шапка, текст и кнопки этого экрана. Каталог, личный кабинет, редактор и графики подгружаются на своём маршруте, а не в общем файле. Один бандл на весь сайт почти всегда даёт длинную задачу на старте.
3. Разбейте длинную работу на короткие куски. Фильтр на тысячи товаров, сортировка и разбор большого ответа сервера не должны идти одним циклом. Список обрабатывают порциями короче 50 миллисекунд и между порциями отдают управление браузеру. Клик проходит между порциями, и эти куски в TBT не попадают. Расчёт, который не рисует интерфейс, уносят в web worker: поток страницы остаётся свободным.
4. Сократите гидратацию. Если страница собрана на сервере, посетитель уже видит готовый HTML. Повторная сборка всего дерева в браузере часто и есть главная длинная задача. Сначала оживляют то, с чем взаимодействуют: меню, поиск, форму. Блоки ниже первого экрана подключают, когда до них доскроллили. Статичный текст в JavaScript не нуждается.
5. Уберите лишние библиотеки со старта. Полный набор функций, тяжёлый слайдер, графики и скрипт анимации на каждой странице держат поток, даже если на экране один абзац. Библиотеку оставляют только там, где она нужна, либо меняют на лёгкий вариант.
6. Не пересчитывайте вёрстку в цикле. Чтение ширины элемента и сразу запись стиля заставляют браузер заново раскладывать страницу на каждом шаге. Сначала читают все размеры, потом один раз записывают изменения. Анимацию делают через transform и opacity: эти свойства не перекладывают весь документ.
7. Облегчите стили и шрифты. Большая таблица стилей и несколько начертаний тоже занимают главный поток: браузер считает правила и готовит текст. На странице оставляют используемые стили и одно-два начертания в формате woff2. На TBT это влияет слабее, чем JavaScript, но на телефоне среднего уровня уже заметно.
8. Не кладите в документ лишние данные. Большой JSON в теле страницы и скрипт, который сразу обходит всё дерево, создают длинную задачу ещё до виджетов. В HTML оставляют данные первого экрана. Остальное запрашивают, когда блок действительно нужен.
Как проверить, что стало быстрее
Цифру смотрят в PageSpeed Insights, отдельно для телефона и компьютера. После каждой правки сравнивают TBT и подсказки «сократите время выполнения JavaScript», «сократите работу главного потока», «избегайте длинных задач» и «уменьшите влияние стороннего кода». В панели Performance браузера длинные задачи отмечены отдельно: видно, какой файл их породил — свой бандл, метрика или виджет.
Проверять стоит на слабом телефоне или в режиме ограничения процессора. Задача, которая на компьютере занимает 40 миллисекунд и в TBT не входит, на телефоне легко растягивается до 200 и начинает копить блокировку.
Полевую проверку смотрят по INP в блоке Core Web Vitals. Лабораторный TBT падает сразу после правки. Полевой INP меняется по мере новых визитов, поэтому расхождение в первые дни нормально. Если TBT уже низкий, а INP слабый, ищут действие, которого нет в тесте Lighthouse: открытие меню, фильтр, шаг в корзине.
Какой результат считать нормальным
Ориентир лаборатории — до 200 миллисекунд. Страница услуг и статья обычно укладываются в эту границу, если чужие виджеты не стартуют вместе с документом. Каталог и карточка товара тоже могут остаться в хорошей зоне, когда свой код разрезан по маршрутам, а фильтр не пересчитывает весь список одним циклом. Рекламный код, без которого страница не живёт, изолируют и не запускают до первого действия: иначе он снова заберёт поток себе.