Вступление

Современные браузеры - очень сложные системы. Они проделывают большую работу перед преобразованием HTML / CSS и JAVASCRIPT в интерактивные страницы. В этой статье мы познакомимся с некоторыми приемами, которые помогут ускорить работу нашего веб-приложения в браузере.

Содержание основано на разделе «Производительность рендеринга» статьи по основам Интернета на сайте developers.google.com. Если вы хотите углубиться в подробности, вы найдете ссылку на исходный документ в разделе ссылок ниже.

Основные части браузера

Компонент пользовательского интерфейса (UI) включает в себя все части, которые видны пользователю, за исключением области рендеринга. Пользовательский интерфейс связан с механизмом рендеринга через механизм браузера. Механизм рендеринга строится из HTML и CSS, страниц, с которыми будет взаимодействовать пользователь. Компонент UI Backend отображает общие графические компоненты, не зависящие от платформы.

Интерпретатор Javascript анализирует и выполняет коды JavaScript. Сетевой компонент загружает удаленный ресурс по протоколу HTTP (S).

Компонент сохранения данных управляет различными данными, которые браузер будет хранить: сеансами, локальным хранилищем файлов cookie и т. Д.

Механизм рендеринга

Механизм рендеринга предназначен для рендеринга страницы из HTML, CSS. Он имеет конвейер с 4-мя основными этапами.

Первый этап

Механизм визуализации анализирует документы HTML и CSS для создания деревьев DOM и CSSOM. Парсер, используемый для HTML-документа, нетрадиционен. Он пытается исправить код вместо отображения сообщений об ошибках.

Второй этап

Деревья DOM и CSSOM будут использоваться для создания дерева рендеринга. Каждый узел в этом дереве сочетает в себе свойства HTML и CSS.

Это дерево будет включать только видимые элементы. Это означает, что он не будет включать элементы с атрибутом display = none.

Третий этап

Layout или Reflow - это название этого этапа. На этом этапе браузер вычисляет координаты для каждого узла в дереве рендеринга.

Четвертый этап

Живопись - название этого этапа. Здесь браузер будет использовать результаты последнего шага для визуализации каждого элемента на экране.

Оптимизация

Первый и второй этапы

CSS

На этом этапе создается CSSOM, который используется для построения дерева рендеринга. Сложность селекторов влияет на время, необходимое для расчета стиля. Чем проще селекторы, тем быстрее будут вычисления. Один из способов подтвердить простоту селекторов - следовать методологии БЭМ (ссылка в справочниках).

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

JAVASCRIPT

Код JAVASCRIPT выполняется в основном потоке, который также используется для других задач. Итак, если код JAVASCRIPT удерживает поток дольше 3–4 мс во время анимации. Пользователь может заметить рывки в своем пользовательском интерфейсе. Чтобы избежать этой проблемы, возможны два решения:

1. Для задач, отнимающих много времени и не требующих доступа к DOM, используйте Web Workers. Они позволяют нам переместить эти задачи в другой поток. В результате это освободит основной ресурс для параллельного поиска других задач.

2. Если задача требует доступа к DOM, решение состоит в том, чтобы разделить задачу на более мелкие задачи, которые не удерживают поток в течение длительного времени. Эти задачи должны выполняться с использованием requestAnimationFrame. Этот последний метод рекомендуется для визуальных изменений, поскольку он может утверждать, что изменения запускаются в нужный момент во время кадра. При использовании для визуальных изменений такие функции, как setTimeout и setInterval, могут вызывать рывки.

Последний совет в этой части - научиться использовать DevTools для анализа производительности кода. Это позволит вам проактивно устранять потенциальный источник проблем.

Третий этап

CSS

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

JAVASCRIPT

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

Время расчетов можете проверить с помощью DevTools.

Используя JAVASCRIPT, все значения макета доступны на основе последнего кадра. В случае, если вы пытаетесь получить доступ к значению макета после изменения геометрических атрибутов некоторых элементов. Браузеру необходимо будет пересчитать стиль и запустить макет, прежде чем предоставлять доступ к этому значению. Стиль и макет запуска раньше, чем прогнозируется, может привести к снижению производительности.

// Чтобы получить доступ к box.offsetHeight, браузер будет вынужден запустить макет

function logBoxHeight () {

box.classList.add («супер-большой»);

console.log (box.offsetHeight);

}

// доступ к значению будет быстрее без принудительного раскладки

function logBoxHeight () {

console.log (box.offsetHeight);

box.classList.add («супер-большой»);

}

Ситуация ухудшается, когда мы пытаемся запустить аналогичный шаблон внутри цикла. В следующем примере: для каждой итерации браузер должен стиль и макет, чтобы получить значение box.offsetWidth. Это связано с редактированием параграфов [i] .style.width в итерации, предшествующей текущей.

function resizeAllParagraphsToMatchBlockWidth () {

for (var i = 0; i ‹paragraphs.length; i ++) {

параграфы [i] .style.width = box.offsetWidth + ‘px’;

}

}

Более разумный способ выполнить ту же задачу - прочитать значение перед входом в цикл:

var width = box.offsetWidth;

function resizeAllParagraphsToMatchBlockWidth () {

for (var i = 0; i ‹paragraphs.length; i ++) {

// Теперь пиши.

параграфы [i] .style.width = width + ‘px’;

}

}

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

Четвертый этап

Помещая компоненты, которые движутся или нуждаются в частом перекрашивании, внутри разных слоев. вы поможете браузеру обработать их, не затрагивая другие элементы. Чтобы создать новый слой с помощью CSS, мы можем использовать атрибут «will-change: transform».

Поскольку каждый уровень требует памяти и управления, эту функцию следует использовать с умеренностью. Чрезмерное использование может привести к падению производительности.

Заключение

В этой статье мы получили представление о внутренней архитектуре современных браузеров и о том, как все работает внутри. Наше основное внимание было уделено механизму рендеринга, который анализирует HTML / CSS для создания визуального документа для пользователя. Мы видели, что процесс внутри двигателя в основном состоит из 4 этапов. У нас есть краткое описание каждого этапа и того, как мы можем помочь браузеру более эффективно запускать наш код.

использованная литература

Https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/#1_1

Https://developers.google.com/web/fundamentals/

Https://developers.google.com/web/fundamentals/performance/rendering/

Https://css-tricks.com/bem-101/

Https://github.com/wilsonpage/fastdom