Оптимизация производительности фронтенда

Проблема производительности и отзывчивости сайта полностью лежит на совести фронтендера. Если сайт тормозит, это не технологии слишком продвинутые или компьютеры слишком слабые, это не клиент придирчивый или дизайнер экзотический, это фронтенд-разработчик не справился со своей работой.

Поэтому разработчикам нужен алгоритм, которому нужно следовать, чтобы тормозящих сайтов (и уходящих пользователей) было меньше:

  1. Уменьшить нагрузку на процессор
    1.1. Использовать меньше памяти
    1.2. Снизить частоту кадров, там где она не важна
    1.3. Использовать все доступные ресурсы, кроме процессора пользователя
  2. Добавить правильную обратную связь
    2.1. Добавить прозрачные однозначные состояния, которые не вводят пользователей в заблуждение
    2.2. Использовать особенности человеческого восприятия, чтобы казалось что интерфейс работает быстрее чем на самом деле
  3. Использовать память для ускорения вычислений



Выступления

FrontendConf в Москве
6 июня, 2017
Holy.js в СПб (PDF, ~20Мб)
3 июня, 2017




ДАМП в Екатеринбурге (PDF, ~15Мб)
апрель

1. Уменьшить нагрузку на процессор

1.1. Использовать меньше памяти

Основной способ сделать так, чтобы приложение работало быстрее — снизить объемы вычислений. Чем меньше структуры данных, на которых нужно выполнить вычисления, тем быстрее вычисления закончатся.

Самый приземленный и доступный пример для веб-разработчиков, с которого стоит начать — снижение размера DOM-дерева. Все элементы, отрисованные на страницы попадают в память вкладки как JS-объекты, с каждым из которых можно призводить определенные операции. Важно понимать, что в DOM-дерево попадают не только элементы, созданные с помощью тегов, например div или span, а вообще все символы из разметки, включая переносы, комментарии, указатель на доктайп и прочее.

Есть разметка, в которой есть ul, три вложенных li, между которыми затесался комментарий.

Если посмотреть на DOM-объекты, которые записаны в ul, будет видно, что он содержит не только три элемента списка, но и комментарий и какие-то текстовые ноды.

Доллар $ это не jQuery, это алиас в консоли Хрома для метода document.querySelector. Такой же алиас $$ есть для document.querySelectorAll

Первая же текстовая нода, которая была создана как потомок списка, содержит только перенос. Таким образом, в DOM-дерево попадают вообще все символы из разметки, в том числе переносы строк.

Кроме того, что DOM-дерево само по себе достаточно объемно, движок JS постоянно производит над ним какие-то операции. Например, если мы прокручиваем страницу, даже на один пиксель, браузеру нужно пересчитать положение всех DOM-элементов и отрисовать их. Пересчет размеров и положения всех элементов будет происходить постоянно, даже если эти элементы находятся вне области видимости пользователя, потому что они могут повлиять на другие элементы на странице.

Таким образом большое DOM-дерево негативно сказывается на производительности браузера и разработчикам очень важно стараться не перегружать его лишними элементами, например убирать из DOM те элементы, которые пользователь прямо сейчас не видит.

Ниже даны ссылки на две тестовые страницы. Внешне они одинаковы, только одна страница содержит 5000 элементов на первом экране, а вторая только 100. Первые экраны этих страниц выглядят одинаково, но при этом вторая страница грузится на порядок быстрее. Вам предлагается с помощью профайлера замерить результаты отрисовки первой страницы и сравнить их между собой.

Медленная страница на 5000 фотографий
Быстрая страница на 1000 фотографий

В первом примере большие страницы переключаются с помощью переключателя страниц в верхней части. Попробуйте попереключать страницы и посмотрите, как быстро они переключаются и как реагирует на это ваш компьютер.

Во втором примере дополнительные DOM-элементы добавляются в конец страницы по мере прокрутки сайта. Обратите внимание, что если зайти достаточно далеко, то производительность сайта так же начинает падать. Это происходит потому что движку становится все сложнее просчитать положение и размеры всех DOM-элементов. Исходя из этого можно сделать вывод, что неплохим способом ускорить производительность будет не только уменьшить изначальный объем DOM-дерева, но и периодически чистить его от элементов, которые находятся вне досягаемости, например, удаляя элементы сверху. Самое радикальное решение при таком подходе — показывать только те элементы, которые находятся в области видимости.


продолжение будет…

1.2. Снизить частоту кадров, там где она не важна

1.3. Использовать все доступные ресурсы, кроме процессора пользователя

2. Добавить обратную связь

3. Оптимизировать память