\n \n \n `);\n});\n```\n\n**HTTP ответ:**\n```http\nHTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\nContent-Length: 1234\nCache-Control: public, max-age=3600\nSet-Cookie: session_id=xyz789; Path=/\n\n\n...\n```\n\n### Этап 6: Парсинг HTML\n\nБраузер читает HTML сверху вниз и строит DOM (Document Object Model).\n\n```html\n\n\n \n My Page\n \n \n \n

Заголовок

\n

Текст

\n \n \n \n\n```\n\n**Важные моменты при парсинге:**\n- **Link tags (CSS)** → блокируют отрисовку (render blocking)\n- **Script tags (JS)** → блокируют парсинг HTML\n- **Img tags** → не блокируют парсинг, загружаются параллельно\n- **IFrame** → загружаются асинхронно\n\n### Этап 7: Загрузка ресурсов\n\nБраузер загружает CSS, JavaScript, изображения параллельно (но с лимитом соединений).\n\n```javascript\n// Схема загрузки (примерно)\nВремя 0 мс: GET index.html\nВремя 50 мс: GET style.css (обнаружена в )\n GET logo.png (обнаружена в )\nВремя 150 мс: GET app.js (обнаружена в \n\n\n\n\n```\n\n### Performance API для измерения\n\n```javascript\n// Измеренияние времени загрузки\nconst perfData = performance.timing;\n\nconst pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;\nconst connectTime = perfData.responseEnd - perfData.requestStart;\nconst renderTime = perfData.domComplete - perfData.domLoading;\n\nconsole.log(`Page Load: ${pageLoadTime}ms`);\nconsole.log(`Network: ${connectTime}ms`);\nconsole.log(`Render: ${renderTime}ms`);\n\n// Modern API\nconst metrics = performance.getEntriesByType('navigation')[0];\nconsole.log(`DNS: ${metrics.domainLookupEnd - metrics.domainLookupStart}ms`);\nconsole.log(`TCP: ${metrics.connectEnd - metrics.connectStart}ms`);\nconsole.log(`TTFB: ${metrics.responseStart - metrics.requestStart}ms`);\nconsole.log(`DOMContentLoaded: ${metrics.domContentLoadedEventEnd}ms`);\n```\n\n### Ключевые Web Vitals\n\n**Метрики для оценки производительности:**\n\n1. **FCP (First Contentful Paint)** — первый контент на экран (< 1.8 сек хорошо)\n2. **LCP (Largest Contentful Paint)** — крупный контент на экран (< 2.5 сек хорошо)\n3. **CLS (Cumulative Layout Shift)** — неожиданные сдвиги элементов (< 0.1 хорошо)\n4. **TTFB (Time To First Byte)** — время до первого байта (< 0.6 сек хорошо)\n5. **FID (First Input Delay)** — задержка при взаимодействии (< 0.1 сек хорошо)\n\n### Оптимизация на backend\n\nБакэнд может значительно улучшить производительность:\n\n```javascript\n// 1. Server-side кэширование\napp.use(compression()); // GZIP сжатие\n\n// 2. HTTP/2 Server Push\nres.push('/style.css', { req: req, res: res, method: 'GET', pathname: '/style.css' });\n\n// 3. CDN для статического контента\napp.use(express.static('public', { maxAge: '1d' }));\n\n// 4. Early hints (103 Early Hints)\nres.writeHead(103, { Link: '; rel=preload; as=style' });\n\n// 5. Быстрая обработка запроса\napp.get('/', async (req, res) => {\n // Оптимизировать запросы к БД\n // Использовать кэширование\n res.send(html);\n});\n```\n\n### Вывод\n\nПроцесс загрузки страницы — это сложное взаимодействие между браузером, сетью и сервером. Backend разработчик должен понимать:\n- Как минимизировать время обработки на сервере\n- Как отправлять оптимальный размер HTML/CSS/JS\n- Как структурировать ответ для лучшего парсинга браузером\n- Какие метрики производительности отслеживать\n\nОптимизация всего процесса — это ключ к быстрым и отзывчивым приложениям.","dateCreated":"2026-03-29T18:48:30.900174","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

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

1.8 Middle🔥 151 комментариев
#API и сетевые протоколы

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

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

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

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

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

Полный цикл загрузки страницы

Вкратце:

1. DNS resolution (преобразование домена в IP)
2. TCP connection (установка соединения с сервером)
3. HTTP request (отправка запроса)
4. Server processing (сервер обрабатывает запрос)
5. HTTP response (получение ответа)
6. HTML parsing (браузер парсит HTML)
7. Resource loading (загрузка CSS, JS, изображений)
8. DOM construction (построение DOM дерева)
9. CSS parsing & CSSOM (построение стиля)
10. Rendering (отрисовка на экран)
11. JavaScript execution (выполнение скриптов)
12. Layout (расчёт позиций элементов)
13. Paint (рисование на canvas)
14. Composite (конечный вывод)

Этап 1-3: Сетевой уровень

DNS Resolution (50-300 мс)

1. Браузер проверяет кэш DNS
2. Если нет — отправляет запрос к DNS серверу
3. DNS сервер возвращает IP адрес
4. Браузер теперь знает, куда подключиться

Пример:
getAddrInfo("example.com") → "93.184.216.34"

TCP Connection (100-300 мс)

1. Браузер инициирует TCP handshake (3-way handshake)
   - SYN пакет от клиента
   - SYN-ACK пакет от сервера
   - ACK пакет от клиента
2. Соединение установлено

Время: зависит от задержки сети (latency)

TLS Handshake (для HTTPS, +100-200 мс)

1. Client Hello → отправляем поддерживаемые версии и шифры
2. Server Hello → сервер выбирает версию и сертификат
3. Certificate validation → браузер проверяет сертификат
4. Key exchange → обмен ключами шифрования
5. Finished → оба стороны готовы

Время: зависит от сложности алгоритма

Этап 4: HTTP запрос

GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Cookie: session_id=abc123

Браузер отправляет запрос и ждёт ответа.

Этап 5: Обработка на сервере

На стороне Node.js сервера:

// Сервер получил запрос
app.get('/', (req, res) => {
  // Обработка (может включать:
  // - запросы к БД
  // - логика приложения
  // - рендеринг шаблона
  // - кэширование
  
  res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>Пример</title>
        <link rel="stylesheet" href="/style.css">
      </head>
      <body>
        <h1>Добро пожаловать</h1>
        <script src="/app.js"></script>
      </body>
    </html>
  `);
});

HTTP ответ:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1234
Cache-Control: public, max-age=3600
Set-Cookie: session_id=xyz789; Path=/

<!DOCTYPE html>
<html>...

Этап 6: Парсинг HTML

Браузер читает HTML сверху вниз и строит DOM (Document Object Model).

<!DOCTYPE html>
<html>
  <head>
    <title>My Page</title>
    <link rel="stylesheet" href="/style.css"> <!-- блокирует парсинг! -->
  </head>
  <body>
    <h1>Заголовок</h1>
    <p>Текст</p>
    <img src="logo.png"> <!-- не блокирует парсинг, но запускает загрузку -->
    <script src="app.js"></script> <!-- блокирует парсинг HTML! -->
  </body>
</html>

Важные моменты при парсинге:

  • Link tags (CSS) → блокируют отрисовку (render blocking)
  • Script tags (JS) → блокируют парсинг HTML
  • Img tags → не блокируют парсинг, загружаются параллельно
  • IFrame → загружаются асинхронно

Этап 7: Загрузка ресурсов

Браузер загружает CSS, JavaScript, изображения параллельно (но с лимитом соединений).

// Схема загрузки (примерно)
Время 0 мс:    GET index.html
Время 50 мс:   GET style.css (обнаружена в <link>)
                GET logo.png  (обнаружена в <img>)
Время 150 мс:  GET app.js    (обнаружена в <script>)
Время 200 мс:  app.js загружен → парсинг HTML продолжается
Время 300 мс:  style.css загружен → может начаться отрисовка
Время 400 мс:  logo.png загружен

HTTP/2 мультиплексирование: В HTTP/2 все ресурсы загружаются по одному соединению параллельно.

Этап 8: DOM Tree Construction

HTML
├── html
│   ├── head
│   │   ├── title
│   │   └── link (style.css)
│   └── body
│       ├── h1
│       ├── p
│       ├── img
│       └── script (app.js)

Этап 9: CSSOM Tree Construction

Браузер парсит CSS и строит CSSOM (CSS Object Model).

/* style.css */
body { margin: 0; background: white; }
h1 { font-size: 32px; color: blue; }
p { line-height: 1.5; }

CSOM Tree:

CSOM
├── body: { margin: 0, background: 'white' }
├── h1: { font-size: '32px', color: 'blue' }
└── p: { line-height: '1.5' }

Этап 10: Render Tree

Браузер объединяет DOM и CSSOM в Render Tree (видимые элементы).

Render Tree = DOM ∩ CSSOM

Элементы которые не отрисовываются:
- display: none элементы
- script, style теги (не видны)
- head элементы

Этап 11: Layout (Reflow)

Браузер рассчитывает позицию и размер каждого элемента.

// Это вызывает reflow (пересчет layouts)
element.offsetWidth;    // чтение положения
element.style.width = '200px'; // изменение стиля
element.offsetHeight;   // чтение положения (reflow снова!)

// Оптимизация: batch reads и writes
const width = element.offsetWidth;  // 1 reflow
const height = element.offsetHeight; // 1 reflow
element.style.width = '200px';      // 1 reflow
element.style.height = '100px';     // 1 reflow
// Всего 3-4 reflows

Этап 12: Paint (Repaint)

Браузер рисует каждый элемент на canvas.

// Это вызывает repaint
element.style.color = 'red'; // изменение цвета (нет reflow, только paint)
element.style.background = 'blue'; // еще paint

Этап 13: Composite

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

// Это самое дешевое (только composite, без reflow/paint)
element.style.transform = 'translateX(100px)'; // composite только
element.style.opacity = 0.5; // composite только

Этап 14: JavaScript Execution

После того, как браузер завершил парсинг, выполняются синхронные скрипты.

// app.js
console.log('Hello'); // выполнится сразу

// Это блокирует отрисовку, пока выполняется
while(true) {} // НИКОГДА не делай так!

// Асинхронный код выполняется после
setTimeout(() => {
  console.log('Позже');
}, 0);

Полная временная шкала

Время (мс)  Событие
0            Пользователь кликнул на ссылку
50           DNS resolution
150          TCP connection + TLS handshake
200          HTTP запрос отправлен
250          Сервер обрабатывает (БД запросы, логика)
350          HTTP ответ начинает приходить (первые байты)
400          Полный HTML получен
450          Парсинг HTML + загрузка CSS
500          CSS полностью загружен
550          Layout (расчет позиций)
600          Paint (рисование)
650          Composite (финальное изображение)
700          JavaScript execution
750          DOM ready (DOMContentLoaded event)
800          Изображения загружены
850          Load event (load event)
900          Page fully interactive

Критические ресурсы (Critical Rendering Path)

Ресурсы которые блокируют отрисовку:

  1. HTML
  2. CSS (находится в head)
  3. JavaScript (синхронные скрипты)

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

<!-- Плохо: CSS в head блокирует отрисовку -->
<head>
  <link rel="stylesheet" href="style.css">
</head>

<!-- Хорошо: CSS с медиа-запросом не блокирует -->
<link rel="stylesheet" href="style.css" media="print">

<!-- Хорошо: async/defer для JS -->
<script src="app.js" defer></script> <!-- загружается параллельно, выполняется после парсинга -->

<!-- Хорошо: CSS в head, но с preload -->
<link rel="preload" href="important.css" as="style">
<link rel="stylesheet" href="style.css">

Performance API для измерения

// Измеренияние времени загрузки
const perfData = performance.timing;

const pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;
const connectTime = perfData.responseEnd - perfData.requestStart;
const renderTime = perfData.domComplete - perfData.domLoading;

console.log(`Page Load: ${pageLoadTime}ms`);
console.log(`Network: ${connectTime}ms`);
console.log(`Render: ${renderTime}ms`);

// Modern API
const metrics = performance.getEntriesByType('navigation')[0];
console.log(`DNS: ${metrics.domainLookupEnd - metrics.domainLookupStart}ms`);
console.log(`TCP: ${metrics.connectEnd - metrics.connectStart}ms`);
console.log(`TTFB: ${metrics.responseStart - metrics.requestStart}ms`);
console.log(`DOMContentLoaded: ${metrics.domContentLoadedEventEnd}ms`);

Ключевые Web Vitals

Метрики для оценки производительности:

  1. FCP (First Contentful Paint) — первый контент на экран (< 1.8 сек хорошо)
  2. LCP (Largest Contentful Paint) — крупный контент на экран (< 2.5 сек хорошо)
  3. CLS (Cumulative Layout Shift) — неожиданные сдвиги элементов (< 0.1 хорошо)
  4. TTFB (Time To First Byte) — время до первого байта (< 0.6 сек хорошо)
  5. FID (First Input Delay) — задержка при взаимодействии (< 0.1 сек хорошо)

Оптимизация на backend

Бакэнд может значительно улучшить производительность:

// 1. Server-side кэширование
app.use(compression()); // GZIP сжатие

// 2. HTTP/2 Server Push
res.push('/style.css', { req: req, res: res, method: 'GET', pathname: '/style.css' });

// 3. CDN для статического контента
app.use(express.static('public', { maxAge: '1d' }));

// 4. Early hints (103 Early Hints)
res.writeHead(103, { Link: '</style.css>; rel=preload; as=style' });

// 5. Быстрая обработка запроса
app.get('/', async (req, res) => {
  // Оптимизировать запросы к БД
  // Использовать кэширование
  res.send(html);
});

Вывод

Процесс загрузки страницы — это сложное взаимодействие между браузером, сетью и сервером. Backend разработчик должен понимать:

  • Как минимизировать время обработки на сервере
  • Как отправлять оптимальный размер HTML/CSS/JS
  • Как структурировать ответ для лучшего парсинга браузером
  • Какие метрики производительности отслеживать

Оптимизация всего процесса — это ключ к быстрым и отзывчивым приложениям.

Как происходит загрузка страницы в браузере? | PrepBro