Раздел «Top linking sites» в Google Search Console, 500 строк на страницу
Я интересуюсь производительностью фронтенда, поэтому не мог удержаться и решил разобраться, в чём дело. В конце концов, Google активно стремится к повышению веб-производительности, поэтому стоит ожидать, что собственные публичные приложения компании будут хорошим эталоном.
Этап 1 — Запись профиля производительности
В подобных случаях невероятно полезны профили производительности: часто бывает достаточно посмотреть отчёт, чтобы понять, почему какой-то элемент имеет низкую производительность. Я открыл DevTools / Performance
и начал запись, немного прокрутил список вниз, а затем остановил запись. И вот что я увидел:
Профиль производительности скроллинга таблицы данных «Top linking sites», очень низкий FPS
Эти красные треугольники в блоках «Task» дают нам понять, что при скроллинге какие-то операции занимают больше времени, чем это приемлемо. Обычно для достижения идеального скроллинга в 60 FPS мы стремимся, чтобы эти блоки выполнялись менее чем за 16 мс. На показанном выше изображении блоки с красными треугольниками в среднем выполняются примерно 150 мс, что приводит приблизительно к 6–7 FPS. Да ладно, Google, ты ведь способен на большее!
Этап 2 — Разбираемся в причинах
Шкала времени наверху показывает, насколько занят CPU различными видами задач: оранжевый цвет — это JavaScript, фиолетовый — это структура и стили, а зелёный — отрисовка. Здесь всё фиолетовое, то есть проблема не в JavaScript, а в DOM/стилизации:
График показывает, что CPU занят обработкой структуры
Это подтверждается каскадным графиком под графиком CPU. В нём используются те же цветовые обозначения и в большинстве записей присутствует много оранжевого и немного меньше фиолетового и зелёного. В нашей записи видно, что время в основном тратится на обновление слоёв, это видно по тексту в фиолетовых блоках, гласящему Update layer tree
:
На каскадном графике видено, что скроллинг тормозит из-за «Update layer tree»
Слои создаются для скроллящегося контента, переводного контента и так далее. Возможно, их очень много? Давайте выясним!
Этап 3 — Изучаем слои
В Chrome DevTools содержится впечатляющее количество полезных инструментов, но некоторые из них найти довольно сложно. Одним из таких скрытых сокровищ является панель Layers; чтобы найти её, нужно нажать кнопку меню в DevTools и выбрать More tools / Layers
. В моём случае это выглядит так:
Панель «Layers» в Chrome DevTools; слой заполнен кучей контента
Слоёв не очень много, но есть парочка огромных. Похоже, в них куча контента, и это приводит нас к выводу о том, что используемый Google datagrid не применяет виртуализированный рендеринг. Частично это объясняет причины торможения, но 500 строк — это всё равно не очень много. Должно быть что-то ещё…
Этап 4 — Изучаем DOM
К сожалению, DOM не особо производителен, когда содержит много элементов. Если бы он был производительным, техники виртуализации, реализованные в различных популярных в вебе data grids на JS, не потребовались бы. На данном этапе мы можем предположить, что таблица рендерит много элементов. Создав Live expression в DevTools Console, вы можете пощёлкать по панели элементов и выяснить это. Переключимся на Console
, нажмём на кнопку Create live expression
(глаз) и введём $0.querySelectorAll('*').length
.
Теперь нажимая на панель Elements
, мы видим следующее, сначала для всей таблицы:
Live expression демонстрирует количество элементов-потомков для выбранного элемента
Как мы видим, для отображения всего 500 строк он создаёт больше 16 тысяч элементов DOM, что немного излишне. Нажав на тело документа, мы увидим следующее:
Куча элементов!
Вся страница содержит больше 38 тысяч (!) элементов, а так быстрое приложение не пишут! Очевидно, что ситуацию можно было бы улучшить, использовав data grid с виртуализированным рендерингом, но давайте посмотрим, можно ли сделать что-то меньшими усилиями.
Этап 5 — Улучшаем ситуацию
Учитывая данные в профиле производительности, я подозреваю, что структура всей страницы создаётся при скроллинге таблицы. А создание структуры такого количества элементов — это затратная операция. Если бы был какой-то способ ограничения её влияния…
Хорошие новости — он существует! Я попробовал применить один тайный рецепт, снова поскроллил, и теперь ситуация стала гораздо лучше. И это чётко видно из следующего профиля производительности:
Скроллинг сильно улучшился!
Каждый кадр теперь занимает примерно 16 мс, и мы скроллим почти на 60 FPS вместо 6–7. Потрясающе!
Что же я сделал? Просто добавил одну строку CSS в <table>
на панели Elements
, указав, что таблица не должна влиять на структуру или стили других элементов страницы:
table {
contain: strict;
}
Вот так:
Вот и всё, десятикратное увеличение скорости благодаря одной строке CSS. Вы можете попробовать «починить» свою Google Search Console.
Подробнее о CSS-свойстве contain
можно узнать в MDN.
Автор: Алексей