\n\n// ХОРОШО - defer (загружается параллельно, выполняется после HTML)\n\n\n// ХОРОШО - async (загружается параллельно, выполняется сразу)\n\n\n// ХОРОШО - динамический скрипт (не блокирует)\nconst script = document.createElement('script');\nscript.src = 'analytics.js';\ndocument.head.appendChild(script);\n```\n\n## 7. Render Tree Construction\n\n```javascript\n// Комбинирует DOM + CSSOM для понимания что отрисовывать\n// Исключает: display: none, , , и т.д.\n\nconst renderTree = {\n html: { /* стили */ },\n body: { /* стили */ },\n h1: { /* видимо */ },\n p: { /* видимо */ },\n hidden: null // display: none - не входит\n};\n\n// Render tree строится только после:\n// 1. DOM полностью спарсен\n// 2. CSSOM полностью спарсен\n// Это создаёт время ожидания (Render Blocking Resources)\n```\n\n## 8. Layout (Reflow)\n\n```javascript\n// Браузер вычисляет позицию и размер каждого элемента\nconst layout = {\n процесс: \"Tree traversal - пройти по каждому узлу\",\n вычисления: [\n \"Box model: content, padding, border, margin\",\n \"Position: static, relative, absolute, fixed, sticky\",\n \"Display: block, inline, flex, grid\",\n \"Width/height: auto, px, %, viewport units\"\n ],\n результат: \"Layout tree с координатами (x, y, width, height)\"\n};\n\n// Дорогие операции (trigger reflow):\nconst expensive = [\n \"element.offsetWidth - читать размер\",\n \"element.style.width = '100px' - изменить размер\",\n \"appendChild() - добавить элемент\",\n \"window.getComputedStyle() - запросить стили\"\n];\n\n// Оптимизация:\nfunction batchMeasurements() {\n // ПЛОХО\n for (let i = 0; i < 1000; i++) {\n elements[i].style.width = elements[i].offsetWidth + 10 + 'px';\n // Каждая итерация trigger reflow!\n }\n \n // ХОРОШО\n const widths = elements.map(el => el.offsetWidth);\n elements.forEach((el, i) => {\n el.style.width = (widths[i] + 10) + 'px';\n // Один раз читаем, один раз пишем\n });\n}\n```\n\n## 9. Paint (Rasterization)\n\n```javascript\n// Браузер преобразует layout в пиксели\nconst paint = {\n процесс: \"Заполнить цветом согласно CSS\",\n что_включает: [\n \"Цвета фона\",\n \"Бордеры\",\n \"Текст\",\n \"Тени\",\n \"Изображения\"\n ]\n};\n\n// Paint timing разбивается на:\nconst paintStages = {\n \"First Paint (FP)\": \"Первый пиксель (обычно background)\",\n \"First Contentful Paint (FCP)\": \"Первый контент (текст, изображение)\",\n \"Largest Contentful Paint (LCP)\": \"Самый большой элемент загружен\"\n};\n\n// Оптимизация:\n// - Меньше paint-затратных свойств (box-shadow, opacity изменения)\n// - Использовать will-change для hint браузеру\n// - Избегать частых перекрашиваний\n```\n\n## 10. Composite (GPU Layer)\n\n```javascript\n// Браузер объединяет слои для финального отображения\nconst composite = {\n слои: \"Каждый элемент может быть отдельным слоем\",\n когда_создаётся: [\n \"transform: translate(), scale(), rotate()\",\n \"opacity изменение\",\n \"position: fixed / sticky\",\n \"will-change: transform\"\n ]\n};\n\n// Оптимизация:\n// Используй transform вместо top/left\n// ПЛОХО:\nfunction animate() {\n element.style.left = position + 'px'; // trigger reflow + paint\n}\n\n// ХОРОШО:\nfunction animate() {\n element.style.transform = `translateX(${position}px)`; // только composite\n}\n```\n\n## Полный цикл в цифрах\n\n```javascript\nconst timeline = {\n DNS: \"20-120ms\",\n TCP_TLS: \"50-300ms\",\n request_response: \"50-200ms\",\n parsing_html: \"100-500ms\",\n parsing_css: \"0-300ms (параллельно с HTML)\",\n parsing_js: \"100-500ms (блокирует!)\",\n dom_cssom_ready: \"~500-1000ms\",\n layout: \"50-200ms\",\n paint: \"50-200ms\",\n composite: \"10-50ms\",\n total: \"1000-4000ms\"\n};\n\n// Core Web Vitals:\nconst metrics = {\n \"LCP\": \"Largest Contentful Paint: < 2.5s\",\n \"FID\": \"First Input Delay: < 100ms\",\n \"CLS\": \"Cumulative Layout Shift: < 0.1\"\n};\n```\n\nПонимание этого процесса критично для оптимизации производительности. Каждый этап - это точка оптимизации.","dateCreated":"2026-04-03T17:54:39.093013","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как происходит процесс формирования страницы браузером?

1.7 Middle🔥 152 комментариев
#Браузер и сетевые технологии

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

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

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

Процесс формирования страницы браузером (Critical Rendering Path)

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

1. DNS Lookup

// Браузер преобразует домен в IP адрес
const step1 = {
  что_происходит: "Браузер запрашивает DNS сервер",
  пример: "example.com -> 93.184.216.34",
  время: "20-120ms",
  как_оптимизировать: "DNS prefetch в HTML"
};

// HTML
<link rel="dns-prefetch" href="//api.example.com">

2. Установление соединения (TCP/TLS)

// Браузер подключается к серверу
const step2 = {
  tcp: "Three-way handshake: SYN -> SYN-ACK -> ACK",
  tls: "SSL/TLS handshake для HTTPS",
  время: "50-300ms",
  оптимизация: "Keep-Alive, HTTP/2, HTTP/3"
};

// HTTP/2 позволяет множественные стримы на одном соединении

3. HTTP Request и Response

// Браузер отправляет GET запрос
const request = {
  метод: "GET /index.html HTTP/1.1",
  заголовки: {
    "Host": "example.com",
    "User-Agent": "Mozilla...",
    "Accept": "text/html,application/xhtml+xml",
    "Accept-Encoding": "gzip, deflate, br"
  }
};

// Сервер отправляет HTML
const response = {
  статус: "200 OK",
  headers: {
    "Content-Type": "text/html; charset=utf-8",
    "Content-Length": "15234",
    "Cache-Control": "max-age=3600"
  },
  body: "<!DOCTYPE html><html>..."
};

4. Parsing HTML (DOM Construction)

// Браузер анализирует HTML построчно (streaming)
const htmlParsing = {
  порядок: [
    "1. <!DOCTYPE html> - режим отрисовки",
    "2. <meta charset> - кодировка",
    "3. <meta viewport> - responsive",
    "4. <link rel=stylesheet> - CSS (БЛОКИРУЮЩИЙ)",
    "5. <script> - JS (БЛОКИРУЮЩИЙ)",
    "6. <body> - начинается отрисовка"
  ],
  
  результат: "DOM tree - дерево узлов с тегами и атрибутами"
};

// Пример DOM tree
const domTree = {
  documentElement: {
    tagName: "HTML",
    children: [
      {
        tagName: "HEAD",
        children: [
          { tagName: "TITLE", textContent: "My Page" },
          { tagName: "LINK", attributes: { rel: "stylesheet", href: "style.css" } }
        ]
      },
      {
        tagName: "BODY",
        children: [
          { tagName: "H1", textContent: "Hello" },
          { tagName: "P", textContent: "World" }
        ]
      }
    ]
  }
};

5. Parsing CSS (CSSOM Construction)

// Браузер загружает и анализирует CSS
const cssLoading = {
  критическое: "CSS в <head> блокирует отрисовку",
  некритическое: "CSS с media queries не блокирует",
  оптимизация: `
    <!-- Критическое - в head -->
    <link rel="stylesheet" href="critical.css">
    
    <!-- Некритическое - загружается асинхронно -->
    <link rel="preload" href="other.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
  `
};

// CSSOM tree - Object Model из CSS
const cssom = {
  selectors: {
    "body": { fontSize: "16px", color: "#333" },
    "h1": { fontSize: "32px", fontWeight: "bold" },
    "p": { margin: "10px" }
  }
};

6. Parsing JavaScript

// Проблема: <script> БЛОКИРУЕТ parsing HTML
// Браузер останавливается, выполняет JS, потом продолжает HTML

// ПЛОХО - blocking script
<script src="app.js"></script>

// ХОРОШО - defer (загружается параллельно, выполняется после HTML)
<script src="app.js" defer></script>

// ХОРОШО - async (загружается параллельно, выполняется сразу)
<script src="analytics.js" async></script>

// ХОРОШО - динамический скрипт (не блокирует)
const script = document.createElement('script');
script.src = 'analytics.js';
document.head.appendChild(script);

7. Render Tree Construction

// Комбинирует DOM + CSSOM для понимания что отрисовывать
// Исключает: display: none, <head>, <meta>, <link> и т.д.

const renderTree = {
  html: { /* стили */ },
  body: { /* стили */ },
  h1: { /* видимо */ },
  p: { /* видимо */ },
  hidden: null  // display: none - не входит
};

// Render tree строится только после:
// 1. DOM полностью спарсен
// 2. CSSOM полностью спарсен
// Это создаёт время ожидания (Render Blocking Resources)

8. Layout (Reflow)

// Браузер вычисляет позицию и размер каждого элемента
const layout = {
  процесс: "Tree traversal - пройти по каждому узлу",
  вычисления: [
    "Box model: content, padding, border, margin",
    "Position: static, relative, absolute, fixed, sticky",
    "Display: block, inline, flex, grid",
    "Width/height: auto, px, %, viewport units"
  ],
  результат: "Layout tree с координатами (x, y, width, height)"
};

// Дорогие операции (trigger reflow):
const expensive = [
  "element.offsetWidth - читать размер",
  "element.style.width = '100px' - изменить размер",
  "appendChild() - добавить элемент",
  "window.getComputedStyle() - запросить стили"
];

// Оптимизация:
function batchMeasurements() {
  // ПЛОХО
  for (let i = 0; i < 1000; i++) {
    elements[i].style.width = elements[i].offsetWidth + 10 + 'px';
    // Каждая итерация trigger reflow!
  }
  
  // ХОРОШО
  const widths = elements.map(el => el.offsetWidth);
  elements.forEach((el, i) => {
    el.style.width = (widths[i] + 10) + 'px';
    // Один раз читаем, один раз пишем
  });
}

9. Paint (Rasterization)

// Браузер преобразует layout в пиксели
const paint = {
  процесс: "Заполнить цветом согласно CSS",
  что_включает: [
    "Цвета фона",
    "Бордеры",
    "Текст",
    "Тени",
    "Изображения"
  ]
};

// Paint timing разбивается на:
const paintStages = {
  "First Paint (FP)": "Первый пиксель (обычно background)",
  "First Contentful Paint (FCP)": "Первый контент (текст, изображение)",
  "Largest Contentful Paint (LCP)": "Самый большой элемент загружен"
};

// Оптимизация:
// - Меньше paint-затратных свойств (box-shadow, opacity изменения)
// - Использовать will-change для hint браузеру
// - Избегать частых перекрашиваний

10. Composite (GPU Layer)

// Браузер объединяет слои для финального отображения
const composite = {
  слои: "Каждый элемент может быть отдельным слоем",
  когда_создаётся: [
    "transform: translate(), scale(), rotate()",
    "opacity изменение",
    "position: fixed / sticky",
    "will-change: transform"
  ]
};

// Оптимизация:
// Используй transform вместо top/left
// ПЛОХО:
function animate() {
  element.style.left = position + 'px'; // trigger reflow + paint
}

// ХОРОШО:
function animate() {
  element.style.transform = `translateX(${position}px)`; // только composite
}

Полный цикл в цифрах

const timeline = {
  DNS: "20-120ms",
  TCP_TLS: "50-300ms",
  request_response: "50-200ms",
  parsing_html: "100-500ms",
  parsing_css: "0-300ms (параллельно с HTML)",
  parsing_js: "100-500ms (блокирует!)",
  dom_cssom_ready: "~500-1000ms",
  layout: "50-200ms",
  paint: "50-200ms",
  composite: "10-50ms",
  total: "1000-4000ms"
};

// Core Web Vitals:
const metrics = {
  "LCP": "Largest Contentful Paint: < 2.5s",
  "FID": "First Input Delay: < 100ms",
  "CLS": "Cumulative Layout Shift: < 0.1"
};

Понимание этого процесса критично для оптимизации производительности. Каждый этап - это точка оптимизации.