Какие рекомендации по написанию производительного кода в браузере?
Что проверяют
Умеете ли вы говорить о производительности через метрики и причины, а не через список советов. Следом обычно спрашивают, как вы найдёте, почему страница тормозит при прокрутке, или что такое INP.
Как отвечать
Опирайтесь на Core Web Vitals: LCP (хорошо до 2,5 с), INP (до 200 мс, в 2024 году заменил FID) и CLS (до 0,1). Дальше рычаги по группам:
- загрузка: разбиение кода через динамический
import(), скрипты сdefer, сжатие Brotli, современные форматы AVIF и WebP сsrcset. Для главной картинкиfetchpriority="high", для остальныхloading="lazy"; - главный поток: задачи дольше 50 мс блокируют ввод. Тяжёлые вычисления в Web Worker, длинные циклы дробят на части с уступкой потоку через
scheduler.yield()там, где он поддерживается, илиsetTimeout. Прокрутку и ресайз обрабатывают сthrottleи пассивными слушателями{ passive: true }; - рендеринг: анимируют
transformиopacity, их обрабатывает композитор без пересчёта раскладки. Пакетные изменения DOM, делегирование событий вместо тысячи слушателей,content-visibility: autoдля длинных страниц; - стабильность:
widthиheightу картинок и резерв места под баннеры, иначе растёт CLS; - кэш: хэш в имени файла и
Cache-Control: max-age=31536000, immutable, Service Worker для офлайна; - память: снимайте слушатели и таймеры, следите за отсоединёнными узлами DOM.
Диагностика: вкладка Performance в DevTools, Lighthouse для лабораторных замеров, библиотека web-vitals или отчёт CrUX для реальных пользователей.
Где спотыкаются
Ставят loading="lazy" на все картинки, включая главную над первым экраном. Браузер откладывает загрузку LCP-изображения, и метрика ухудшается.
Чередуют чтение и запись геометрии в цикле: меняют стиль, читают offsetHeight, снова меняют. Каждое чтение заставляет браузер синхронно пересчитать раскладку. Сначала все чтения, потом все записи.
Оптимизируют по Lighthouse на мощном ноутбуке. Лабораторный замер не видит INP реальных пользователей на слабых телефонах, смотреть надо полевые данные.