Уменьшение прокрутки при использовании переполнения-y: прокрутка;
У меня есть макет из двух столбцов, правый столбец - это списки с прокручиваемыми результатами с максимальным количеством результатов 200 элементов (в основном, только с установкой ul с overflow-y: scroll;
)
То, что я нахожу, заключается в том, что при прокрутке в правой колонке возникает некоторый jank (что особенно заметно на аппаратном уровне).
В хронологической шкале времени я могу увидеть некоторое большое "Дерево обновления слоя", пока я прокручиваю столбец.
Есть ли способ понять, почему "Update Layer tree" настолько длинный и что свойства CSS влияют на скорость больше всего?
Когда я нажимаю на него - просто дает мне информацию о том, как долго он побежал, и ничего больше.
У меня есть некоторый CSS в каждом из li, который не очень хорошо работает (например, фильтры, трансформирует, box-shadows и т.д.) -
Если я удаляю каждый файл SASS один за другим, он улучшает производительность прокрутки (и в конечном итоге удаляет jank после удаления всего CSS), но, очевидно, его трудно определить, какие свойства css не выполняют этого.
Интересно, не потеряет ли что-нибудь что-то в хромированной шкале времени, которая может быть полезна в этом отношении?
Я попытался использовать свойство CSS will-change
для продвижения прокрутки к другому ускорению аппаратного обеспечения уровня/силы, но это не имеет большого значения.
Кроме того, во время прокрутки нет событий javascript.
Ограничение до менее 200 элементов не является вариантом.
У меня есть пример этого (я знаю его более длинный список элементов, но это только для демонстрационных целей):
https://github.com/jooj123/jank/blob/master/scroll.html
Что действительно интересно, если я удаляю overflow-y: scroll;
(в .map-search__results в примере выше), прокрутка становится очень гладкой, а jank исчезает - почему это так сильно влияет?
Вот хромовая шкала времени (с в основном только длинными разделами "Обновление слоя" ):
![введите описание изображения здесь]()
Fix:
Пол отвечает о will-change: transform
на месте, в частности, этот лакомый кусочек помог:
"Добавить will-change: transform;. После добавления" repaints on scroll "rect исчез."
НО просто будьте осторожны, так как это обычно не применяется в зависимости от вашей базы кода, проверьте индикатор производительности прокрутки, чтобы убедиться, что "repaints on scroll" выключен, для меня мне также пришлось отключить свойство -webkit-clip-path
(в моем фактическая база кода - не в демонстрационной версии), которая была установлена в одном из дочерних div, см.:
![введите описание изображения здесь]()
Ответы
Ответ 1
Я опробовал вашу тестовую страницу и посмотрел.
Во-первых, с прокруткой перфомансов мне нравится перелистывать несколько флажков на панели Rendering:
![введите описание изображения здесь]()
Мгновенно мы видим, как этот div вызывается как "repaints on scroll". Затем вы можете проверить, что на панели экспериментальных слоев:
![введите описание изображения здесь]()
(я щелкнул правой кнопкой мыши в дереве и выбрал "Показывать внутренние слои" ).
Теперь большие затраты на дерево уровня обновления обычно вызывают LOTS слоев или несколько слоев, которые очень велики в размерах. В этом случае у нас действительно нет ни того, ни другого. Но у нас есть прокручиваемый слой, который не получается сгруппированной прокруткой.
Сложная прокрутка == быстрая прокрутка == обычно по умолчанию. Но в таких случаях мы возвращаемся к "прокрутке основной нити", которая действительно медленная и сочная. С положительной стороны, crbug.com/381840 будет исправлено, что должно автоматически исправить этот тестовый пример. Ура! Но сейчас мы можем обойти это.
Обходной путь
Вы упомянули, что вы пробовали will-change
, и это не имело никакого эффекта, но попытка его сама по себе отлично справилась. Он принадлежит элементу, который имеет overflow
, в этом случае его селектор .map-search__results
. Добавьте will-change: transform;
. После добавления "repaints on scroll" rect исчез. И измерение с временной шкалой впоследствии, и это намного лучше.
Здесь пред/после:
ссылка на просмотр
Удачи!
Ответ 2
Если ваша проблема заметна для вас во время прокрутки, вы должны иметь возможность открывать вкладки шкала времени и стилей в инструментах разработчика, снимите отметки со стилей, которые применяются к вашим элементам один за другим на вкладке стилей и посмотреть, как это влияет на прокрутку. Таким образом, вы можете тестировать каждое правило стиля независимо, а не целые файлы CSS. И если вы используете sourcemaps в своем CSS, вы можете легко найти правило нарушения в ваших фактических файлах CSS и внести коррективы.
Если вы не знакомы с использованием вкладки стилей: при открытии инструментов разработчика Chrome используйте инструмент инспектора (верхний левый угол панели разработчика), чтобы выбрать объекты, которые, как вы подозреваете, могут дать вам проблемы. Все стили, связанные или переопределенные для выбранного элемента, будут указаны на вкладке стилей. Затем вы можете отключить их один за другим. Вы можете использовать инспектор для сверления так глубоко, как вы хотите, через вложенные элементы.
UPDATE:
Я снял код после редактирования и внимательно посмотрел на него. Я заметил, что переполнение у вас было на вашем элементе ul
. Лично я никогда не использовал переполнение на ul
(обычно предпочитая для этого контейнер, например div
), поэтому из любопытства я удалил overflow-y:scroll
из вашего ul
и поместил его на ul, содержащий div .right-content
(и установите высоту на 100%), и прокрутка janky исчезла.
Что касается причин, я могу только догадываться, но я считаю, что это связано с количеством прокручиваемых элементов. Когда ваш переполнение находится на UL, вы прямо прокручиваете ВСЕ те дочерние элементы li
. Когда он содержит div
, вы на самом деле прокручиваете ТОЛЬКО ul
, поэтому я считаю, что этот процесс имеет гораздо меньшую математику, чтобы определить при расчете позиционирования движущихся объектов. 1 div для настройки по сравнению с сотнями li для настройки.
![сравнение красок]()
Если вы сравните сроки в изображениях выше, вы увидите разницу. Верхняя часть - это оригинальная версия с overlflow-y:scroll
на ul
. Вы можете навести курсор на все эти маленькие строки в дереве обновлений и увидеть, что нарисованы сотни предметов. Это ваши элементы li
. Во второй временной шкале находится версия, в которой я удалил переполнение из ul
и применил его к содержащему div
. Вы можете видеть на этой временной шкале, что в дереве обновлений есть только один элемент для рисования, который является ul
. Если вы посмотрите на размеры предметов, вы также увидите разницу в размере.