Skip to content

Latest commit

 

History

History
341 lines (197 loc) · 23.9 KB

15.optimization.md

File metadata and controls

341 lines (197 loc) · 23.9 KB

Web Vitals

Web Vitals — инициатива Google, разработанная для того, чтобы получать сигналы о качестве пользовательского опыта, который испытывают посетители вашего сайта.

Каждый параметр Core Web Vitals представляет собой отдельную часть пользовательского опыта, который измерен и отражает критические показатели, ориентированные на хорошее юзабилити посетителей сайта.

Core Web Vitals - не искусственные, а данные живые

  1. Синтетические тесты не решают реальных проблем пользователей - картина необъективна, хотя и более очевидна.
  2. Все данные – от реальных посетителей вашего сайта. Если у них возникают проблемы при его посещении, то в отчете это будет видно.
  3. Пользовательский опыт посетителей вашего сайта лучше отражает его качество.

Largest Contentful Paint (LCP) - Отрисовка самого крупного контента

https://web.dev/lcp/

Измеряет производительность загрузки.

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

На LCP влияют четыре фактора:

  • медленное время ответа сервера;
  • блокирующие рендеринг JavaScript и CSS;
  • время загрузки ресурса;
  • клиентский рендеринг.

Как улучшить:

Сначала нужно определиться, какой элемент является LCP

  1. Если картинка, проверяем, что она не отложена
  2. Если картинка - добавляем в прелоад
  3. Если текст – добавляем шрифты в прелоад.
  4. Сместить фокус с медленного элемента
  5. Отказаться от фоновых изображений
  6. Спроектировать более простой дизайн первого экрана

First Input Delay (FID) - задержка первого ввода

https://web.dev/fid/

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

Как правило, задержка ввода возникает из-за того, что основной поток браузера занят чем-то другим, поэтому он (пока) не может отвечать пользователю.

Основная причина плохого значения FID «тяжелое» выполнение JavaScript.

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

Как улучшить:

  1. Разбиваем выполнение JS на мелкие задачи.
  2. Откладываем функционал, не нужный для отрисовки.

Cumulative Layout Shift (CLS) - неожиданные смещения макета

https://web.dev/cls/

Параметр, который измеряет визуальную стабильность сайта.

Показатель смещения элемента на странице во время загрузки, в процентах.

Элементы могут смещаться из-за подгрузки изображений, шрифтов, рекламных блоков

Как улучшить:

Резервируйте место под элементы, которые появляются после загрузки основного контента (реклама, сторонние виджеты, отложенные изображения, iframe)

FCP - Первая отрисовка контента

https://web.dev/fcp/

Метрика FCP (Первая отрисовка контента) измеряет время с момента начала загрузки страницы до момента, когда какая-либо часть содержимого страницы отобразится на экране.

alt

TTFB - Время до первого байта

https://web.dev/ttfb/

TTFB — это метрика, которая измеряет время между запросом ресурса и началом поступления первого байта ответа.

Улучшение TTFB во многом зависит от вашего хостинг-провайдера и стека серверных приложений. Высокие значения TTFB могут быть связаны с одной или несколькими из следующих проблем:

  • Услуги хостинга с неадекватной инфраструктурой для обработки высоких нагрузок трафика
  • Веб-серверы с недостаточным объемом памяти, что может привести к перегрузке
  • Неоптимизированные таблицы базы данных
  • Неоптимальная конфигурация сервера базы данных

Основа:

  • Устранение ресурсов, блокирующих рендеринг
  • Минимизация CSS-кода - JS
  • Удаление неиспользуемого CSS-JS-кода
  • Уменьшение времени ответа сервера (TTFB)
  • Обслуживание статических объектов сайта с помощью эффективной политики кеширования
  • Уход от чрезмерного размера DOM
  • Настройка показа текста во время загрузки веб-шрифтов
  • Уход от переадресации нескольких страниц
  • Поддержание малого количества запросов и объемов передаваемых данных
  • Предварительное подключение к нужным источникам
  • Предварительная загрузка ключевых запросов
  • Уход от огромных нагрузок на сеть
  • Минимизация глубины вложенности критических запросов (это серии зависимых сетевых запросов, важных для рендеринга страницы. Чем больше длина цепочек и чем больше размер загрузки, тем значительнее влияние на производительность загрузки страницы.)

Скрипты: async, defer

defer

Атрибут defer сообщает браузеру, что он должен продолжать обрабатывать страницу и загружать скрипт в фоновом режиме, а затем запустить этот скрипт, когда DOM дерево будет полностью построено.

  • Скрипты с defer никогда не блокируют страницу.
  • Скрипты с defer всегда выполняются, когда дерево DOM готово, но до события DOMContentLoaded.

Отложенные с помощью defer скрипты сохраняют порядок относительно друг друга, как и обычные скрипты.

<script defer src="https://javascript.info/article/script-async-defer/long.js"></script>
<script defer src="https://javascript.info/article/script-async-defer/small.js"></script>

(Маленький скрипт загрузится первым, но выполнится вторым)

async

Атрибут async означает, что скрипт абсолютно независим:

  • Страница не ждёт асинхронных скриптов, содержимое обрабатывается и отображается.
  • Событие DOMContentLoaded и асинхронные скрипты не ждут друг друга:
  • DOMContentLoaded может произойти как до асинхронного скрипта так и после асинхронного скрипта
  • Остальные скрипты не ждут async, и скрипты c async не ждут другие скрипты.
<script async src="https://javascript.info/article/script-async-defer/long.js"></script>
<script async src="https://javascript.info/article/script-async-defer/small.js"></script>

(скрипты выполняются в порядке загрузки.)

Итого

У async и defer есть кое-что общее: они не блокируют отрисовку страницы. Так что пользователь может просмотреть содержимое страницы и ознакомиться с ней сразу же.

Resource Hints

Resource Hints — это инструкции для браузера, которые можно использовать для повышения производительности веб-сайта. Этот набор инструкций помогает браузеру в определении приоритетов источников или ресурсов, которые необходимо получить и обработать.

preload

<link rel= "preload"> говорит браузеру как можно скорее загрузить и кэшировать ресурс (например, скрипт или таблицу стилей). Это полезно, когда ресурс понадобится через несколько секунд после загрузки страницы — и вы хотите ускорить процесс.

Браузер ничего не делает с ресурсом после загрузки. Скрипты не выполняются, таблицы стилей не применяются. Ресурс просто кэшируется и немедленно предоставляется по запросу.

prefetch

<link rel= "prefetch"> просит браузер загрузить и кэшировать ресурс (например, скрипт или таблицу стилей) в фоновом режиме. Загрузка происходит с низким приоритетом, поэтому не мешает более важным ресурсам. Это полезно, если ресурс понадобится на следующей странице, а вы хотите заранее его кэшировать.

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

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

preconnect - dns-prefetch

<link rel="preconnect"> просит браузер заранее подключиться к домену, когда вы хотите ускорить установку соединения в будущем.

<link rel="dns-prefetch"> просит браузер заранее выполнить резолвинг DNS для домена, если вы скоро будете подключаться к нему и хотите ускорить начальное соединение.

dns-prefetch «стучится», чтобы проверить расположение сайта

preconnect открывает дверь.

Поиск DNS – процесс поиска доменного имени в сети и его перевода в IP-адрес – может занимать от десяток до сотен миллисекунд. Если пользователь уже на вашем сайте, его браузер уже знает его положение… но если вы загружаете ресурсы с других сайтов на свой страницу, браузеру нужно время на обработку информации DNS по каждому из них, так как он находит их в HTML. Вы можете предвосхитить этот процесс, поместив dns-prefetch для внешних сайтов в своей страницы.

Для подключения к каждому сайту браузер должен выполнить следующие действия:

Резолвинг DNS. Найти IP-адрес сервера (216.58.215.78) для указанного доменного имени (google.com).

Рукопожатие TCP. Обмен пакетами (клиент → сервер → клиент), чтобы инициировать TCP-соединение с сервером.

Рукопожатие TLS (только для сайтов HTTPS). Два раунда обмена пакетами (клиент → сервер → клиент → сервер → клиент), чтобы инициировать безопасный сеанс TLS.

prerender

<link rel="prerender"> просит браузер загрузить URL-адрес и отобразить его на невидимой вкладке. Когда пользователь нажимает на ссылку, страница должна отобразиться немедленно. Это полезно, если вы уверены, что пользователь посетит определённую страницу, и хотите ускорить её отображение.

Работа браузера

Critical render path

Critical render path — это набор действий и ресурсов, которые браузер должен совершить, загрузить и обработать, чтобы пользователь получил свой первый результат, пригодный для работы.

Сделать запрос (DNS resolve, TCP поход и т.п.);

Получить HTML-документ;

Спарсить HTML;

Построить DOM tree (document object model);

alt

Отправить запросы критических ресурсов. CSS, блокирующий JS;

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

Получить весь CSS-код (также запускает запросы на JS-файлы);

Построить CSSOM tree;

На данном этапе браузер берет DOM, берет CSS, собирает соответствия, и на выходе мы получаем объектную модель для CSS.

alt

Выполнить весь полученный JS-код. Здесь могут вызываться layout, если из js кода происходит форсирование reflow;

Перестроить DOM tree (при необходимости);

Построить Render tree;

Последний шаг на этапе от формирования деревьев к рендеру. На этом этапе формируется дерево, которое будет рендериться.

alt

Отрисовать страницу (layout → paint → Composite).

layout, paint и Composite, являются основными этапами отвечающими за отрисовку страницы в веб-браузере.

Layout - Reflow

Для того чтобы отобразить элементы на странице, браузеру необходимо понимать какого размера эти элементы и где они располагаются. Браузер проходит по рендер дереву (Render Tree), начиная от корневого элемента дерева и определяет координаты каждого элемента и пространство которое он занимает.

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

Layout отвечает за:

  • Вычисление слоев
  • Расчет взаиморасположения элементов на слое
  • Расчет влияния одних элементов на другие

Для оптимизации нужно:

  • Уменьшать количество DOM нод
  • По возможности избегать layout (избегать reflow)
  • Компоновать чтение и запись свойств

Reflow: Происходит при (кроме transform):

  • Считывании параметров, связанных с размерами
  • Установке параметров, связанных с размерами
div1.style.margin = "200px";
var height1 = div1.clientHeight;
div2.classList.add("foobar");
var height2 = div2.clientHeight;
doSomething(height1, height2);


div1.style.margin = "200px";
div2.style.height = '100px';
var height1 = div1.clientHeight;
var height2 = div2.clientHeight;

alt

https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FZTnIxIA5KGw%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DZTnIxIA5KGw&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FZTnIxIA5KGw%2Fhqdefault.jpg&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=youtube

Paint - Repaint

На этом шаге отрисовываем элементы.

Браузер начинает придавать правильный вид элементам, которые были помещены в Rendered Tree, таким как цвета фона или размеры шрифта.

Composite

После того как браузер знает размеры, позицию и то в какой последовательности красить элементы, наступает пора конечной отрисовки элементов на странице. Для этого браузер на этапе Composite группирует различные элементы по слоям, растрирует эти слои, то есть отрисовывает пиксели и затем объединяет эти слои в готовую страницу в отдельном потоке композитора

Misc

https://rashidovr.medium.com/reflow-repaint-composite-%D1%87%D1%82%D0%BE-%D1%8D%D1%82%D0%BE-%D0%B8-%D0%BA%D0%B0%D0%BA-%D1%8D%D1%82%D0%BE-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82-a777c5760295

https://habr.com/ru/company/hh/blog/513940/

https://habr.com/ru/post/517594/

https://habr.com/ru/post/224187/

https://web.dev/rendering-on-the-web/

Intersection Observer

https://doka.guide/js/intersection-observer/

Intersection Observer — браузерный API, который позволяет асинхронно отслеживать пересечение элемента с его родителем или областью видимости документа (viewport). В момент пересечения можно запустить какое-либо действие, например, подгрузить дополнительные посты в ленте новостей («бесконечный скролл») или сделать «ленивую» загрузку контента.

throttle - debounce

https://doka.guide/js/throttle/

https://doka.guide/js/debounce/

window.addEventListener('scroll', function() {
  console.log('scroll!')
});

image

async

Декодирование изображения называется асинхронным, если оно не препятствует представлению другого контента. Это приводит к более быстрому представлению контента без изображений. Однако содержимое изображения отсутствует на экране до завершения декодирования. После завершения декодирования на экране появляется изображение.

sync

Декодирование изображения называется синхронным, если оно предотвращает представление другого контента до его завершения. Как правило, это приводит к атомарному представлению изображения и любого другого контента одновременно. Однако это представление задерживается на время, необходимое для выполнения декодирования.

retina

https://htmlacademy.ru/blog/html/retina

Чем больше физических пикселей на экране, тем выше его плотность и тем детальнее выводимое на него изображение. Для измерения плотности экранов используют специальную единицу PPI — Pixels per Inch (Пикселей на дюйм, Плотность пикселей). Она показывает количество физических пикселей на квадратном дюйме экрана. То есть чем выше PPI, тем лучше графика.

alt

devicePixelRatio

Misc

https://partytown.builder.io/

https://gwfh.mranftl.com/fonts

https://svgsprit.es/

python3 -m http.server