⚡️ Прощай, FID. Привет, INP: Главная метрика Core Web Vitals
First Input Delay (FID) официально ушел на пенсию в марте 2024 года. На его место пришел INP (Interaction to Next Paint). Если вы всё еще оптимизируете старую метрику, самое время пересмотреть свои подходы.
В чем был обман FID?
FID измерял только задержку (Input Delay) от клика до того момента, как браузер начал выполнять ваш обработчик событий.
Если ваша функция onClick после старта зависала на 2 секунды, перебирая огромный массив, FID всё равно мог быть идеальным (например, 3 мс), хотя пользователь видел намертво зависший интерфейс.
Что измеряет INP?
INP фиксирует всё время до появления визуального отклика на экране:
1. Ожидание освобождения Main Thread (Input delay)
2. Выполнение вашего JS-кода (Processing time)
3. Пересчет стилей, Layout и саму отрисовку (Presentation delay)
Хороший INP - это меньше 200 мс. Причем берется не среднее значение, а один из худших результатов за сессию (98-й перцентиль).
🛠 Как спасать INP (Senior level):
1. Разбивайте Long Tasks (Yield to Main Thread)
Не заставляйте браузер делать всю тяжелую работу за один присест. Дайте ему возможность «вздохнуть» и отрисовать кадр. В современных браузерах для этого внедряется scheduler.yield().
async function handleHeavyClick() {
// 1. Показываем лоадер (синхронно, легко)
showSpinner();
// 2. Отдаем управление браузеру, чтобы он успел отрисовать лоадер!
// Если scheduler.yield недоступен, используем await new Promise(r => setTimeout(r, 0))
if ('scheduler' in window && 'yield' in scheduler) {
await scheduler.yield();
} else {
await new Promise(resolve => setTimeout(resolve, 0));
}
// 3. Теперь делаем тяжелую работу
processHugeData();
}
2. Используйте startTransition в React 18+
Если клик вызывает обновление состояния, которое требует тяжелого рендера (например, фильтрация большого списка), React может заблокировать отрисовку того же чекбокса, на который вы нажали.
Оберните тяжелое обновление стейта в startTransition - React пометит его как низкоприоритетное и не будет блокировать UI.
3. Избегайте Layout Thrashing
Если в обработчике клика вы сначала читаете размеры элемента (el.offsetHeight), а потом меняете классы, вы заставляете браузер синхронно пересчитывать стили (Forced Synchronous Layout). Это убивает фазу Presentation Delay. Сначала читайте, потом пишите!
CodeBase | Frontend | #js
481 ·