\n \n\n```\n\nБраузер создаёт **DOM дерево**:\n\n```\nDocument\n ↓\nhtml\n ├─ head\n │ ├─ title \"My Page\"\n │ └─ link\n │\n └─ body\n ├─ h1 \"Hello World\"\n ├─ p \"Some text\"\n └─ script\n```\n\n### Процесс парсинга: токенизация\n\n**Браузер разбивает HTML на токены:**\n\n```html\n
Hello
\n ↓\nТокены:\n├─ StartTag: div\n├─ Attribute: class=\"container\"\n├─ Text: Hello\n└─ EndTag: div\n```\n\n**Парсер строит дерево из токенов:**\n\n```javascript\n// Внутри браузера происходит примерно так:\n\nconst htmlString = '
Hello
'\n\n// 1. Токенизация\nconst tokens = tokenize(htmlString)\n// [\n// { type: 'startTag', name: 'div', attributes: { class: 'container' } },\n// { type: 'text', content: 'Hello' },\n// { type: 'endTag', name: 'div' }\n// ]\n\n// 2. Построение дерева\nconst dom = buildTree(tokens)\n// div.container\n// └─ text: \"Hello\"\n```\n\n### Инкрементальный парсинг\n\n**Браузер начинает парсить ДО того, как весь файл загружен:**\n\n```\nВремя →\n\nВремя 0ms: <- браузер начинает парсить\n \nВремя 50ms: <- браузер уже парсит дальше\n \nВремя 100ms: <- загружает CSS\n \n \nВремя 200ms:

Hello

<- браузер парсит и отображает\n

Text

\nВремя 300ms: \n \n \n

Hello

\n \n\n```\n\n**Решение: используй async или defer:**\n\n```html\n\n\n\n\n\n\n\n\n```\n\n### CSS и парсинг\n\n**CSS не блокирует парсинг HTML**, но блокирует рендеринг:\n\n```html\n\n \n\n\n

Hello

\n \n\n```\n\n### Полный процесс браузера\n\n**После загрузки и парсинга HTML браузер:**\n\n```\n1. HTML парсинг → DOM дерево\n ↓\n2. CSS парсинг → CSSOM (CSS Object Model)\n ↓\n3. Объединение DOM + CSSOM → Render Tree\n ↓\n4. Layout (вычисление позиций и размеров)\n ↓\n5. Paint (отрисовка на экране)\n ↓\n6. Composite (объединение слоёв)\n```\n\n### Особенности парсинга\n\n**1. Автозакрытие тегов**\n\nБраузер автоматически закрывает незакрытые теги:\n\n```html\n\n
\n

Text\n

\n\n\n
\n

Text

\n
\n```\n\n**2. Исправление структуры**\n\n```html\n\n\n \n \n\n\n
Data
\n \n \n \n \n \n
Data
\n```\n\n**3. Игнорирование неизвестных элементов**\n\nБраузер просто игнорирует теги, которые не знает:\n\n```html\nContent\n\n\n```\n\n### Оптимизация парсинга\n\n**1. Минимизируй блокирующие ресурсы**\n```html\n\n\n \n \n \n\n\n\n\n \n\n```\n\n**2. Загружай CSS в head**\n```html\n\n \n\n```\n\n**3. Загружай скрипты в конце body**\n```html\n\n
\n \n\n```\n\n**4. Используй preload для критичных ресурсов**\n```html\n\n \n \n\n```\n\n### Performance метрики, связанные с парсингом\n\n```javascript\n// FCP (First Contentful Paint)\n// Когда браузер отрисовал первый контент\n\n// LCP (Largest Contentful Paint)\n// Когда загрузился основной контент\n\n// FID (First Input Delay)\n// Задержка при первом взаимодействии с пользователем\n// Часто из-за выполнения скриптов во время парсинга\n\n// Performance API\nconst perfData = performance.getEntriesByType('navigation')[0]\nconsole.log('DOM Interactive:', perfData.domInteractive)\nconsole.log('DOM Content Loaded:', perfData.domContentLoaded)\nconsole.log('Load Complete:', perfData.loadEventEnd)\n```\n\n### Итоговый процесс\n\n```\n1. Браузер получает HTML от сервера\n2. Начинает читать файл построчно (инкрементально)\n3. Создаёт токены из HTML\n4. Строит DOM дерево из токенов\n5. ЕСЛИ встречает
← Назад к вопросам

Как браузер парсит HTML файл?

1.8 Middle🔥 201 комментариев
#HTML и CSS

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

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

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

Как браузер парсит HTML файл

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

Этапы парсинга

1. Получение и загрузка файла

Браузер отправляет HTTP запрос на сервер
    ↓
Сервер отправляет HTML ответ
    ↓
Браузер начинает получать данные

2. Парсинг и построение DOM

Браузер читает HTML построчно:

<!DOCTYPE html>
<html>
  <head>
    <title>My Page</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <h1>Hello World</h1>
    <p>Some text</p>
    <script src="script.js"></script>
  </body>
</html>

Браузер создаёт DOM дерево:

Document
  ↓
html
  ├─ head
  │  ├─ title "My Page"
  │  └─ link
  │
  └─ body
     ├─ h1 "Hello World"
     ├─ p "Some text"
     └─ script

Процесс парсинга: токенизация

Браузер разбивает HTML на токены:

<div class="container">Hello</div>
        ↓
Токены:
├─ StartTag: div
├─ Attribute: class="container"
├─ Text: Hello
└─ EndTag: div

Парсер строит дерево из токенов:

// Внутри браузера происходит примерно так:

const htmlString = '<div class="container">Hello</div>'

// 1. Токенизация
const tokens = tokenize(htmlString)
// [
//   { type: 'startTag', name: 'div', attributes: { class: 'container' } },
//   { type: 'text', content: 'Hello' },
//   { type: 'endTag', name: 'div' }
// ]

// 2. Построение дерева
const dom = buildTree(tokens)
// div.container
//   └─ text: "Hello"

Инкрементальный парсинг

Браузер начинает парсить ДО того, как весь файл загружен:

Время →

Время 0ms:  <html>        <- браузер начинает парсить
              <head>
Время 50ms:   <title>      <- браузер уже парсит дальше
              </title>
Время 100ms:  <link rel=stylesheet href="style.css">  <- загружает CSS
              </head>
              <body>
Время 200ms:   <h1>Hello</h1>  <- браузер парсит и отображает
              <p>Text</p>
Время 300ms:   <script src="script.js">  <- СТОП! Парсинг приостановлен
                                          <- пока загружается script
Время 400ms:  </body>
              </html>       <- весь файл загружен

Блокирующие ресурсы

Скрипты блокируют парсинг:

<!DOCTYPE html>
<html>
  <head>
    <script src="heavy-script.js"></script>  <!-- Парсинг СТОИТ -->
  </head>
  <body>
    <h1>Hello</h1>  <!-- Не будет отображено пока не загрузится скрипт -->
  </body>
</html>

Решение: используй async или defer:

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

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

<!-- Без атрибутов: блокирует парсинг -->
<script src="script.js"></script>

CSS и парсинг

CSS не блокирует парсинг HTML, но блокирует рендеринг:

<head>
  <link rel="stylesheet" href="style.css">  <!-- Загружается асинхронно -->
</head>
<body>
  <h1>Hello</h1>  <!-- HTML парсится, но страница не отображается -->
                   <!-- пока не загружается CSS -->
</body>

Полный процесс браузера

После загрузки и парсинга HTML браузер:

1. HTML парсинг → DOM дерево
        ↓
2. CSS парсинг → CSSOM (CSS Object Model)
        ↓
3. Объединение DOM + CSSOM → Render Tree
        ↓
4. Layout (вычисление позиций и размеров)
        ↓
5. Paint (отрисовка на экране)
        ↓
6. Composite (объединение слоёв)

Особенности парсинга

1. Автозакрытие тегов

Браузер автоматически закрывает незакрытые теги:

<!-- Неправильное HTML -->
<div>
  <p>Text
</div>

<!-- Браузер исправляет это -->
<div>
  <p>Text</p>  <!-- браузер добавил </p> -->
</div>

2. Исправление структуры

<!-- Неправильное HTML -->
<table>
  <tr>
    <td>Data</td>

<!-- Браузер исправляет -->
<table>
  <tbody>  <!-- добавил -->
    <tr>
      <td>Data</td>
    </tr>
  </tbody>  <!-- добавил -->
</table>

3. Игнорирование неизвестных элементов

Браузер просто игнорирует теги, которые не знает:

<custom-element>Content</custom-element>
<!-- Это не стандартный HTML тег, но браузер не выдаёт ошибку -->
<!-- (Web Components используют такие элементы) -->

Оптимизация парсинга

1. Минимизируй блокирующие ресурсы

<!-- ❌ Плохо -->
<head>
  <script src="script1.js"></script>
  <script src="script2.js"></script>
  <script src="script3.js"></script>
</head>

<!-- ✅ Хорошо -->
<head>
  <script src="script.js" defer></script>
</head>

2. Загружай CSS в head

<head>
  <link rel="stylesheet" href="style.css">  <!-- Оптимально -->
</head>

3. Загружай скрипты в конце body

<body>
  <div id="app"></div>
  <script src="script.js"></script>  <!-- В конце -->
</body>

4. Используй preload для критичных ресурсов

<head>
  <link rel="preload" href="critical-script.js" as="script">
  <link rel="preload" href="font.woff2" as="font" type="font/woff2">
</head>

Performance метрики, связанные с парсингом

// FCP (First Contentful Paint)
// Когда браузер отрисовал первый контент

// LCP (Largest Contentful Paint)
// Когда загрузился основной контент

// FID (First Input Delay)
// Задержка при первом взаимодействии с пользователем
// Часто из-за выполнения скриптов во время парсинга

// Performance API
const perfData = performance.getEntriesByType('navigation')[0]
console.log('DOM Interactive:', perfData.domInteractive)
console.log('DOM Content Loaded:', perfData.domContentLoaded)
console.log('Load Complete:', perfData.loadEventEnd)

Итоговый процесс

1. Браузер получает HTML от сервера
2. Начинает читать файл построчно (инкрементально)
3. Создаёт токены из HTML
4. Строит DOM дерево из токенов
5. ЕСЛИ встречает <script> — приостанавливает парсинг (обычно)
6. Загружает и выполняет скрипт
7. Продолжает парсинг
8. Когда весь HTML спарсен — парсинг завершён
9. Браузер вычисляет стили (CSSOM)
10. Объединяет DOM + CSSOM в Render Tree
11. Вычисляет позиции (Layout)
12. Отрисовывает на экране (Paint)

Понимание этого процесса помогает оптимизировать загрузку страницы и улучшить Core Web Vitals.

Как браузер парсит HTML файл? | PrepBro