В сегодняшней статье мы обсудим, как можно улучшить оформление ваших веб-сайтов и веб-приложений. Эта та область, которую мы веб-разработчики, только недавно начали более детально анализировать. Это очень важное направление, поскольку оно может оказывать влияние на взаимодействие с пользователем и приобретение положительного опыта.
Показатель частоты кадров также применим и к интернету.
Частота кадров – это скорость, с которой устройство воспроизводит последовательность изображений на экране. Низкий показатель отображения кадров в секунду (FPS) означает, что отдельные кадры могут быть видны для человеческого глаза. Высокий показатель FPS дает пользователям ощущение адаптивности. Вы, вероятно, уже сталкивались ранее с этим понятием в основном в мире игр, но его также можно отнести и к интернету.
Продолжительное декодирование изображений, ненужное изменение размеров изображений, большие по весу анимации и обработка данных — все это может привести к пропуску кадров, в результате чего снижается общая частота кадров на странице. Далее мы постараемся объяснить, что именно подразумевается под сокращением “jank”.
Для чего нужен показатель частоты кадров?
Плавность при высоком показателе частоты кадров может способствовать привлечению пользователей и может повлиять на процесс взаимодействия пользователей с вашим сайтом или приложением.
В начале этого года на EdgeConf, Facebook подтвердил это А/В тестированием, прокрутка была замедлена от 60 до 30 кадров, в результате чего наступил настоящий коллапс. Тем не менее, если вы пытаетесь, но не можете реализовать высокую частоту смены кадров, и показатель в 60 кадров за секунду находится вне досягаемости, то вы, по крайней мере, хотите достигнуть эффекта плавности. Если вы работаете над созданием собственной анимации, это одна из выгод от использования requestAnimationFrame
: браузер может динамически регулировать сохранение нормальной частоты кадров.
В случаях, когда вы не уверены в оптимальном режиме прокрутки, браузер может управлять частотой кадров вместо вас. Но если ввести большое количество jank, то браузер не будет в состоянии правильно выполнять свою работу. Поэтому старайтесь избегать больших дополнений, таких как массивная заливка, продолжительное выполнение JavaScript кода и вообще всего массивного.
Не нужно предполагать, тестируйте!
Прежде чем начать, мы должны сделать шаг назад и взглянуть на наш подход. Все мы хотим, чтобы наши веб-сайты и приложения работали как можно быстрее. Очень часто люди предпочитают заплатить, чтобы им написали код, который работает не только правильно, но быстро. Разработчики, как правило, всегда очень заняты и если заканчиваются сроки проектирования, то они идут самым простым путем и пользуются фрагментами кода, созданными ранее или же о которых читали и слышали. Когда они так делают, нередко возникают проблемы, поскольку функциональные возможности и оформление браузеров быстро меняются, и то, что медленно работает сегодня, может работать быстро завтра.
Еще один момент о котором нельзя забывать: ваше приложение или веб-сайт является уникальным, и, следовательно, проблемы производительности, с которыми вы вероятно столкнетесь, будут сильно зависеть от особенностей проектирования. Оптимизация игры значительно отличается от оптимизации приложения, которое пользователи могут держать открытым в течение 200 и более часов. Если вы создаете игру, то нужно сосредоточить свое внимание на основных циклах и максимально оптимизировать кусок кода, который будет интегрирован в каждом кадре. С большим по весу DOM-приложением, распределение памяти может быть самой большой проблемой в области производительности.
Вам необходимо детально проанализировать характеристики своего приложения и понять, что будет делать код. Таким образом, если даже с браузером и произойдут какие-то изменения, вы все равно будете четко представлять себе, что важно для вас и вашей команды и сможете принимать обоснованные решения. Так что, несмотря ни на что, предполагаю выполнить тестирование вашего приложения!
В ближайшее время мы собираемся обсудить, как можно измерить частоту кадров и эффективно нанести расцветку. Так что приготовьтесь!
Примечание: некоторые из инструментов, упомянутых в данной статье, требуют наличия Chrome Canary, с использованием «Инструментальных средств разработчика» при активированном about:flags
(Мы — Адди Османи и Пол Льюис — являемся инженерами в команде Разработчиков связей в Chrome).
Изучение конкретного случая: Pinterest.
На днях мы посетили сайт Pinterest, пытаясь добавить подходящее изображение пони в рабочую область (Адди любит пони!). Итак, мы перешли на сайт Pinterest и начали прокрутку страницы, просматривая изображения пони.
Адди добавляет подходящее изображение пони на свой сайт Pinterest. Увеличенная версия.
Jank влияет на условия работы пользователя.
Первое, на что мы обратили внимание – на то, что прокрутка этой страницы не очень хорошо работает — прокрутка вверх и вниз требует определенных усилий при достаточно вялой динамике движения. Когда пользователи сталкиваются с подобной ситуацией, то остаются недовольными, что, скорее всего, приведет к отказу от пользования данным сайтом. А это естественно последнее, что мы ждем от пользователей!
Проблема Pinterest заключается в неудачной реализации механизма прокрутки. Увеличенная версия.
Это прерывание в последовательной частоте кадров именно то, что команда Chrome называет “jank” (хлам), и мы не уверены в причинах возникновения этого эффекта на данном сайте. Вы можете заметить как некоторые из кадров искажаются во время прокрутки. Но давайте представим себе это! Мы собираемся открыть кадровый режим и показать как все будет выглядеть в замедленном варианте.
Примечание: то, что мы действительно ищем – это стабильно высокий FPS, идеально соответствующий частоте обновления экрана. Во многих случаях, это будет значение в 60 FPS, но этот показатель не гарантирует достижения оптимального результата, так что советую провести тестирование для конкретного устройства.
С точки зрения разработчиков на JavaScript, в качестве главной причины мы должны рассматривать нерациональное распределение памяти. Возможно, некоторые проблемные участки кода будут отредактированы уже после завершения проекта. Реальность, однако, такова, что на сегодняшний день проблема очень редко заключается в JavaScript коде. Основные проблемы с производительностью зависят от оформления и времени рендеринга. DOM должен быть включен в пиксели на экране. Из-за избытка элементов оформления пользователь может страдать от замедления прокрутки.
Примечание: HTML5 Rocks специально обсуждает некоторые из причин медленной прокрутки. Если вы чувствуете, что можете столкнуться с этой проблемой, то стоит ознакомиться с данной статьей.
Мера использования элементов рисования.
Частота смены кадров.
Мы подозреваем, что что-то на этой странице влияет на частоту отображения кадров. Итак, давайте откроем Chrome’s Developer Tools (Инструментальные средства разработки Chrome) и перейдем в режим “Timeline” и “Frames” для записи новой сессии. Мы нажмем на кнопку записи и начнем прокрутку страницы, таким же образом как это делают обычные пользователи. Теперь, чтобы имитировать несколько минут использования, мы собираемся делать прокрутку немного быстрее.
Использование Инструментальных средств разработки Chrome для отображения процесса прокрутки. Увеличенная версия.
Вверх, вниз, вверх, вниз. Сейчас вы увидите много фиолетового и зеленого цвета на изображении. Эти цвета соответствуют процессам рисования и рендеринга. Давайте остановим запись на любом моменте. По мере того, как мы будем перелистывать различные кадры, можно будет наблюдать некоторые довольно длительные паузы “Повторной обработки стилей” и множество “Шаблонов”.
Если вы посмотрите на легенду в правой части, то увидите, что мы на самом деле не достигли отметки 60 FPS. Во многих случаях эта отметка даже не дотягивает до показателя 30 FPS. Попросту это связано с довольно слабой реализацией. Теперь каждый из этих баров в итоговом представлении соответствует одному кадру — т.е. всей работе, которую Chrome должен проделать для того, чтобы иметь возможность отобразить приложение на экране.
Инструментальные средства разработки Chrome показывают долгую временную линию процесса рисования. Увеличенная версия.
Время, отведенное для кадра.
Если вы ориентируетесь на отметку в 60 FPS, которая обычно содержит оптимальное количество кадров, то в соответствии с частотой обновления устройств, которые мы обычно используем, вы будете иметь всего 16,7 миллисекунды на выполнение всех операций— JavaScript кода, верстки, декодирования изображений, изменения размеров, рисования, композиционной обработки — в общем всего.
Примечание: получение постоянного показателя частоты кадров является идеальным вариантом. Если вы по каким-либо причинам не можете достигнуть отметки 60 FPS, то лучше всего будет остановиться на доступной величине 30 FPS, а не использовать переменную частоту кадров от 30 до 60 FPS. На практике достичь этого может быть очень сложно, поскольку после завершения выполнения кода JavaScript еще должно быть сделано множество различных работ по формированию шаблона, прорисовке и созданию составных изображений. Предугадать все это раньше времени очень сложно. В любом случае, независимо от используемой вами частоты кадров, убедитесь, что она последовательна и не прерывается (В противном случае процесс отображения будет выглядеть как заикание).
Если вы стремитесь организовать отображение на недорогих устройствах, таких как мобильные телефоны, то не нужно стремиться к времени отображения кадра в 16 миллисекунд. Для этих целей в действительности больше походит значение от 8 до 10 миллисекунд. Подобный принцип может быть также применим и для персонального компьютера, где время отображения кадра может быть увеличено в результате различных процессов браузера. Если вы нерационально организуете распределение времени, то существует вероятность некорректного отображения кадров и появления на странице «jank». Итак, старайтесь, использовать показатель где-нибудь ближе к интервалу от 8 до 10 миллисекунд, но обязательно нужно протестировать используемое устройство, чтобы получить реальное представление о временной шкале.
Чрезвычайно продолжительная отработка макета, более 500 миллисекунд. Увеличенная версия.
Примечание: вы также можете ознакомиться со статьей о том, как использовать инструментальные средства разработки Chrome для нахождения и исправления проблем с производительностью рендеринга. Таким образом, вы сможете уделить больше внимания работе над оптимизацией временной шкалой.
Возвращаясь к проблеме с прокруткой, у нас возникло подозрение о наличии большого количества ненужных перерисовок, происходящих на этой странице с onscroll
.
Одна из самых распространенных ошибок – это заполнение слишком большим количеством JavaScript кода onscroll
обработчика страницы. Это приводит к затруднению правильного распределения времени, отводимого на кадр. Выравнивание работы сборочной линии рендеринга (например, путем помещения его в requestAnimationFrame
) дает вам немного больше времени, но все равно для выполнения всех действий у вас будет только несколько миллисекунд.
Лучшее, что вы можете сделать, это просто зафиксировать значение scrollTop
в обработчике прокрутки, а затем использовать самое последнее значение внутри requestAnimationFrame
.
Прорисовка прямоугольников.
Давайте вернемся к Developer Tools → Settings
и включим функцию «Отображение прорисовки прямоугольников». Это действие поможет визуализировать области экрана, которые прорисованы хорошо заметной красной подсветкой. Теперь посмотрим, что происходит, когда мы выполняем прокрутку на сайте Pinterest.
Активация функции “Прорисовка прямоугольников” в Инструментальных средствах разработчики Chrome. Увеличенная версия.
Раз в несколько миллисекунд, мы наблюдаем большие яркие вспышки красного по всей ширине экрана. Вероятнее всего, что причина этого явления в прорисовке всего экрана каждый раз, когда выполняется прокрутка, которая потенциально является очень ценной. То, что мы хотим видеть – это браузер, который в точности отображает новые элементы на странице. Обычно при прокрутке в поле зрения попадает в основном только нижняя или верхняя часть страницы. Хорошим решением проблемы с прокруткой стало бы создание кнопки “Вернуться к началу страницы” в правом нижнем углу. Поскольку пользователь выполняет прокрутку, фиксированный заголовок в верхней части страницы должен быть перерисован, так же как и кнопка. Таким образом, Chrome должен создать объединение из двух областей, которые должны быть перерисованы.
Chrome показывает только что перерисованные области красной рамкой. Увеличенная версия.
В этом случае, прямоугольник расположен начиная с верхнего левого угла и до правого верхнего угла, занимая не очень широкую область. Кроме этого мы можем также увидеть и прямоугольник в правом нижнем углу. У нас оставляет прямоугольник, расположившийся из верхнего левого угла в правый нижний угол, что, по сути, является областью всего экрана! Если вы посмотрите на кнопку в Инструментальных средствах разработки и либо скроете ее (с помощью H
ключа), либо удалите, а затем выполните прокрутку снова, то увидите, что только область заголовка перекрашена. Способ решения этой конкретной проблемы заключается в размещении кнопки прокрутки в отдельном слое, для того чтобы не возникало объединения с заголовком. Подобное действие по существу позволит изолировать кнопку и исключить связь с остальной частью страницы. Более подробно о слоях и связях мы поговорим немного позже.
Следующий момент, который мне хотелось бы отметить касается зависания. Когда мы находимся в области кнопки, Pinterest закрашивает бар, содержащий функции “Пожаловаться, комментировать и мне нравится” — назовем это панелью действий. Когда мы наводим курсор на одну из кнопок, то закрашивается не только бар, но и все элементы, лежащие в его основе. Закрашивание должно осуществляться только для тех элементов, которые будут изменены визуально.
Основная причина для беспокойства: наличие красных вспышек свидетельствует о многочисленных процессах прорисовки. Увеличенная версия.
Существует и другая интересная вещь касательно прокрутки. Нужно задержать курсор над кнопкой и снова начать прокрутку страницы.
Каждый раз, когда мы прокручиваем новые строки изображений, панель действий окрашивает еще одну кнопку, хотя на нее мы не хотим выполнять наведение. Эта проблема касается UX (пользовательский опыт) больше, чем что-либо другое. Производительность прокрутки в этом случае может играть более важную роль, чем эффект при наведении во время прокрутки. Во время прокрутки, при наведении курсора на кнопку jank усиливается, поскольку браузер, по сути, делает паузу, чтобы прерваться и выполнить прорисовку (то же самое происходит, когда мы откатываемся от элементов!). Один из вариантов решения проблемы заключается в использовании команды setTimeout
с задержкой для того, чтобы бар окрашивал элемент только тогда, когда пользователь действительно намерен его использовать. О данном подходе, мы рассказывали в статье “Как избежать ненужных прорисовок“. Более агрессивный подход будет связан с измерением зна …
Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров