Files
frontend-docs/docs/browser/04-critical-render-path.md
2025-10-31 13:47:50 +03:00

113 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
sidebar_position: 4
---
# Critical render path
Критический путь рендеринга (Critical Rendering Path, CRP) — это последовательность шагов, которые браузер выполняет для преобразования HTML, CSS и JavaScript в пиксели на экране. Оптимизация критического пути рендеринга важна для ускорения загрузки и отображения веб-страниц, что напрямую влияет на пользовательский опыт.
## Основные этапы критического пути рендеринга:
1. **Загрузка и парсинг HTML:**
- Браузер загружает HTML-документ и начинает его парсить.
- Во время парсинга браузер встречает ссылки на внешние ресурсы (CSS, JavaScript, изображения) и начинает их загружать.
При встрече с тегом \<link\> (CSS) или \<script\> (JS) — загрузка может приостанавливаться:
- CSS — блокирует рендеринг (нельзя построить layout без стилей).
- JS — может блокировать парсинг HTML, если не имеет async или defer.
- Браузер преобразует HTML в дерево DOM.
- Каждый HTML-элемент становится узлом в DOM.
2. **Загрузка и парсинг CSS:**
- Когда браузер встречает CSS-файлы, он их загружает и строит CSSOM (CSS Object Model)..
- CSSOM представляет собой дерево стилей, где каждый узел соответствует CSS-правилу.
- CSSOM используется для определения стилей элементов.
3. **Создание дерева рендеринга (Render Tree):**
- Браузер объединяет DOM и CSSOM в дерево рендеринга.
- Дерево рендеринга содержит только видимые элементы (например, элементы с `display: none` не включаются).
- Каждому видимому узлу назначаются стили (цвет, размер, шрифт и т.д.).
4. **Компоновка (Layout):**
- Браузер рассчитывает положение и размеры каждого элемента на странице.
- Этот процесс также называется **рефлоу (reflow)**.
- Результат — `layout tree` с точными координатами.
5. **Отрисовка (Paint):**
- Браузер отрисовывает пиксели на экране на основе данных из дерева рендеринга.
- Этот процесс включает в себя растеризацию (rasterization) и отрисовку слоев.
6. **Композиция (Composite):**
- Браузер объединяет слои (например, элементы с `position: fixed` или анимации) для финального отображения.
![Critical render path](images/04-crp-1.png)
### 🧠 Визуальное резюме
```text
HTML → DOM
CSS → CSSOM
DOM + CSSOM → Render Tree
Render Tree → Layout
Layout → Paint → Composite → Screen
```
### ⚡ Что замедляет CRP
- **Большие или блокирующие CSS/JS** → откладывают построение render tree.
- **Много вложенных или тяжёлых стилей** → усложняют layout и paint.
- **Синхронные JS-скрипты** без async/defer.
- **Шрифты с блокирующей загрузкой** (@font-face без font-display).
## Как оптимизировать критический путь рендеринга?
Оптимизация CRP направлена на ускорение загрузки и отображения контента, особенно "выше сгиба" (above the fold). Основные подходы:
1. **Минимизация размера файлов:**
- Сжимайте HTML, CSS и JavaScript (например, с помощью Gzip или Brotli).
- Удаляйте лишние пробелы, комментарии и неиспользуемый код.
2. **Уменьшение количества ресурсов:**
- Объединяйте CSS и JavaScript-файлы.
- Используйте встроенные стили для критического CSS (Critical CSS).
3. **Оптимизация загрузки CSS:**
- Разделяйте CSS на критический и некритический.
- Используйте `media`-атрибуты для загрузки только необходимых стилей:
4. **Оптимизация загрузки JavaScript:**
- Используйте атрибуты async или defer для загрузки скриптов без блокировки рендеринга:
- Переносите скрипты в конец документа (перед закрывающим тегом `</body>`).
5. **Приоритизация загрузки ресурсов:**
- Используйте `<link rel="preload">` для приоритетной загрузки критических ресурсов:
6. **Оптимизация изображений:**
- Используйте современные форматы (WebP, AVIF).
- Сжимайте изображения и используйте `srcset` для адаптивной загрузки.
7. **Минимизация количества рефлоу и репинтов:**
- Избегайте изменения стилей, которые вызывают рефлоу (например, `width`, `height`, `margin`).
- Используйте `transform` и `opacity` для анимаций, так как они не вызывают рефлоу.
8. **Использование кеширования:**
- Настройте кеширование статических ресурсов (CSS, JS, изображения) на стороне сервера.
## Пример оптимизации CRP:
1. **Критический CSS:**
- Встраивайте стили, необходимые для отображения контента "выше", прямо в HTML
2. **Асинхронная загрузка скриптов:**
- Используйте async или defer для загрузки JavaScript
3. **Предзагрузка шрифтов:**
- Загружайте шрифты заранее, чтобы избежать задержек
## 🧩 Где выполняется JavaScript
JavaScript **выполняется во время построения DOM**, то есть ещё **до этапа Render Tree**, если скрипт найден в HTML.
Это происходит **до Layout и Paint**, потому что браузер должен знать, как изменится структура страницы, прежде чем её рисовать.
### 🕹️ Подробно по этапам:
1. **HTML → DOM**
- Когда парсер HTML встречает \<script\>:
- Без `async` и `defer` — парсинг **останавливается**. Браузер загружает и выполняет JS, потом продолжает строить DOM.
- С `defer` — выполнение откладывается до **после построения DOM** (но до `DOMContentLoaded`).
- С `async` — выполняется **сразу после загрузки**, независимо от DOM.
⚠️ Поэтому синхронный JS может **блокировать CRP**, т.к. пока он выполняется — DOM и CSSOM не достраиваются, а рендер не продолжается.
2. **После построения Render Tree**
- Когда JS выполняется в **runtime** (например, после загрузки страницы), он может:
- Изменять DOM (через `document.createElement`, `innerHTML`, и т.д.)
- Изменять стили (через `element.style` или изменение классов)
Эти изменения вызывают **reflow (layout)** и/или **repaint**, что частично повторяет CRP:
```text
DOM update → Render Tree update → Layout → Paint → Composite
```
🚀 **_Источник: DeepSeek, ChatGPT_** \
🚀 **Источник: [https://www.youtube.com/watch?v=Ff_IZrs4GcY](https://www.youtube.com/watch?v=Ff_IZrs4GcY)**