В предыдущей статье мы разобрались с сетевыми ресурсами, выяснили что переход на http/2 позволяет быстрее загружать ресурсы, а в данной статье посмотрим на те ресурсы, что мы загружаем.

Как загружается страница в браузере

Сначала загружается html страница, далее если приоритет не указан и используется http/1, то идет загрузка ресурсов из тега head, это css, js.

После парсинга html браузер создает модель DOM, далее браузер когда видит ссылку на css приостанавливает визуализацию до тех пор пока не загрузит, распарсит css и не построит модель CSSOM.  Это блокирующий процесс в том смысле, что пользователь не увидит содержимого, пока эти ресурсы не будут загружены, спарсены и применены к странице т.е. html и css замедляют загрузку страницы.

Оптимизация CSS

При использовании css фреймворков Bootstrap/Foundation и др., которые содержат большое кол-во css необходимо:

  • выбирать только необходимые компоненты
  • делать  lazy загрузку только того, что необходимо для работы: например если фрейморк используется только для  desktop то убрать стили для mobile, если у вас не используются какие-то селекторы, то их также можно вырезать
  • воспользоваться альтернативами: flexbox и grid.

На мобильных устройствах компиляция может доходить до 300ms. Всегда это нужно отслеживать на новых браузерах.

Оптимизация JS

Jquery cтал популярен благодаря удобным селекторами, но в настоящее время все современные браузеры поддерживают querySelector, querySelectorAll. Работа с событиями возможна через  addEventListener. Работа с классами и атрибутами элементов через classList, setAttribute, and getAttribute.

Библиотеки манипулирующие с DOM напрямую хорошо подходят для быстрого старта проектов, но сильно влияют на производительность. Современные браузеры довольно быстрые, но проблемы возникают когда идет манипуляция большого кол-ва элементов:

  • чтение атрибутов, или имени классов
  • получением child или sibling

Браузеру необходимо искать, проверять и парсить большое кол-во элементов для каждого узла.

Альтернативой является использование чистого JS либо библиотек создающих модель в памяти, и только потом уже отрисовывающих результат в браузер.

Проверим скорость манипуляции элементами через Jquery и VanillaJS, для теста возьмем 1000 операций append, как самую частую операцию при создании страницы динамически.

for(let i = 0; i < 1000; i++) {
	$("div").append("test item "+i);
}
let c = new DocumentFragment()
for(let i = 0; i < 1000; i++) {
   const e = document.createElement('div');
   var t = document.createTextNode("text text.");   
   e.appendChild(t);  
   c.appendChild(e);
}
document.getElementById('div1').appendChild(c);

Тестировать будем на телефоне Sony Xreria XR(4core CPU, 2GB).

Тест 1. JQEURY append operation. Операция append 485 ms.
Тест 2. Vanilla JS. Append операция 

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

В react'e используется такой же принцип:  создается виртуальная модель dom, которая имеет текущее и предыдущее состояние, синхронизирует изменения и изменяет только нужные узлы DOM.