\n\n// Решение: асинхронная загрузка\n \n \n```\n\n**Порядок выполнения:**\n- `` — загружается асинхронно, блокирует рендеринг\n- `
← Назад к вопросам

Из каких этапов состоит отрисовка

1.0 Junior🔥 181 комментариев
#Браузер и сетевые технологии

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Этапы отрисовки в браузере (Rendering Pipeline)

Отрисовка (rendering) — это процесс, при котором браузер преобразует HTML, CSS и JavaScript в пиксели на экране. Понимание этого процесса критически важно для оптимизации производительности и создания плавных интерфейсов.

1. Parsing (Парсинг)

Первый этап — браузер читает и парсит HTML документ:

// Во время парсинга HTML браузер:
// 1. Создаёт DOM (Document Object Model) дерево
// 2. Парсит CSS и создаёт CSSOM (CSS Object Model)
// 3. Встречает <script> — парсинг останавливается, выполняется JS

// Проблема: блокирующие скрипты
<script src="large.js"></script> <!-- парсинг ждёт выполнения -->

// Решение: асинхронная загрузка
<script async src="large.js"></script> <!-- параллельная загрузка -->
<script defer src="large.js"></script> <!-- выполнится после парсинга -->

Порядок выполнения:

  • <link rel="stylesheet"> — загружается асинхронно, блокирует рендеринг
  • <script async> — загружается параллельно, выполняется при готовности
  • <script defer> — загружается параллельно, выполняется после парсинга DOM
  • <script> (без атрибутов) — блокирует парсинг HTML

2. Style Recalculation (Пересчёт стилей)

Браузер объединяет DOM и CSSOM, вычисляя финальные стили для каждого элемента:

// CSS Specificity влияет на производительность
// Избегай глубоких селекторов

// Плохо: .container div.header span.title a { ... }
// Хорошо: .title { ... }

// Браузер считает стили справа налево!
const element = document.getElementById("myElement");
element.style.color = "red"; // Запускает recalculation

Что запускает пересчёт стилей:

  • Изменение класса: element.classList.add("active")
  • Изменение инлайн-стиля: element.style.color = "red"
  • Изменение содержимого: element.textContent = "new"

3. Layout (Макетирование)

Браузер вычисляет размеры и позиции всех элементов:

// Layout зависит от стилей
const width = element.offsetWidth; // Запускает layout!
const height = element.offsetHeight;
const top = element.offsetTop;

// Проблема: Forced Synchronous Layout
for (let i = 0; i < 1000; i++) {
  element.style.width = (element.offsetWidth + 1) + "px";
  // Каждой итерации: layout -> style change -> layout
  // Очень медленно!
}

// Решение: batch читаемые операции, потом все записи
let widths = [];
for (let i = 0; i < 1000; i++) {
  widths.push(element.offsetWidth); // Все reads вместе
}
for (let i = 0; i < 1000; i++) {
  element.style.width = (widths[i] + 1) + "px"; // Все writes вместе
}

Что запускает Layout:

  • Чтение размеров: offsetWidth, offsetHeight, scrollTop, getBoundingClientRect()
  • Изменение размеров: width, height, margin, padding
  • Изменение позиции: top, left, position

4. Paint (Рисование)

Браузер рисует пиксели: текст, цвета, границы, тени и т.д.:

/* Paint-heavy свойства */
text-shadow: 0 0 10px rgba(0, 0, 0, 0.5); /* дорого */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); /* дорого */
filter: blur(10px);                        /* дорого */
border-radius: 50%;                        /* дешево, но зависит от браузера */

/* Paint-cheap */
color: red;       /* дёшево */
background: blue; /* дёшево */

Оптимизация Paint:

// Плохо: может запустить paint без необходимости
element.style.opacity = 0.5; // Все пиксели перерисовываются

// Хорошо: если используешь opacity для анимации
const animation = () => {
  element.style.opacity = value;
  requestAnimationFrame(animation);
};

5. Composite (Композиция)

Браузер объединяет слои (layers) в финальное изображение:

/* Создание новых слоёв улучшает производительность */
.fast-animation {
  will-change: transform;
  transform: translateZ(0); /* GPU acceleration */
  animation: slide 0.5s ease-out;
}

@keyframes slide {
  from { transform: translateX(0); }
  to { transform: translateX(100px); }
}

/* Transform и opacity НЕ запускают layout/paint */
const animate = () => {
  element.style.transform = "translateY(" + distance + "px)";
  requestAnimationFrame(animate);
};

6. Display (Отображение)

Финальное изображение выводится на экран с частотой экрана (обычно 60 FPS = 16.67ms на кадр).

Полный цикл отрисовки

ParseHTML
    |
    v
Create DOM + CSSOM
    |
    v
Recalculate Styles
    |
    v
Layout (Reflow)
    |
    v
Paint (Repaint)
    |
    v
Composite
    |
    v
Display (16.67ms для 60 FPS)

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

requestAnimationFrame (RAP) — выполняется перед отрисовкой:

function animate() {
  element.style.transform = "rotate(" + angle + "deg)";
  angle += 1;
  requestAnimationFrame(animate);
}
animate();

Приоритет операций:

  1. Самые быстрые (GPU-accelerated):

    • transform
    • opacity
    • will-change
  2. Среднее (могут запустить paint):

    • background-color
    • color
    • border
  3. Самые дорогие (запускают layout):

    • Изменение размеров
    • Изменение позиции
    • display, visibility

Инструменты для анализа:

  • Chrome DevTools → Performance tab
  • Профилировка: Frame time, FPS meter, Paint timing

Понимание этих этапов отрисовки позволяет писать код, который работает со скоростью 60+ FPS, создавая гладкие и отзывчивые интерфейсы.