\n \n\n\n```\n\n#### Как браузер парсит:\n\n```\n1. Браузер читает HTML построчно\n |\n v\n2. - установить кодировку\n |\n v\n3. - установить название вкладки\n |\n v\n4. <link rel=\"stylesheet\"> СТОП! ЗАГРУЗИТЬ CSS\n Парсинг приостановлен, ждём CSS\n |\n v\n5. CSS загружен - продолжить\n |\n v\n6. Парсим <body>\n - <h1> добавляется в DOM\n - <img> отправляем запрос на изображение\n - <p> добавляется в DOM\n |\n v\n7. <script src=\"\"> СТОП! ЗАГРУЗИТЬ И ВЫПОЛНИТЬ JS\n Парсинг приостановлен\n Сеть загружает JS\n V8 выполняет JS\n |\n v\n8. Inline <script> выполняется\n |\n v\n9. Парсинг завершён\n```\n\n**Оптимизация:**\n\n```html\n<!-- Неблокирующий CSS -->\n<link rel=\"stylesheet\" href=\"/style.css\" />\n\n<!-- Неблокирующий JS (внизу страницы) -->\n<script src=\"/app.js\" defer></script>\n\n<!-- Или async для независимого JS -->\n<script src=\"/analytics.js\" async></script>\n```\n\n### Шаг 10: Рендеринг (Rendering Pipeline)\n\n#### Построение DOM\n\n```\nHTML\n <html>\n <body>\n <div id=\"app\">Hello</div>\n </body>\n </html>\n |\n v\n DOM Tree\n html\n |\n body\n |\n div#app (text: \"Hello\")\n```\n\n#### Построение CSSOM\n\n```\nCSS\n body { margin: 0; }\n #app { color: blue; }\n |\n v\n CSSOM Tree\n body { margin: 0 }\n |\n #app { color: blue; margin: 0 (наследовано) }\n```\n\n#### Создание Render Tree\n\nОбъединение DOM и CSSOM:\n\n```\nDOM + CSSOM\n |\n v\n Render Tree\n (только видимые элементы)\n \n body { margin: 0 }\n |\n div#app { color: blue, margin: 0 }\n \n (display: none элементы не включаются)\n```\n\n### Шаг 11: Выполнение JavaScript\n\n```javascript\n// Синхронный JS блокирует рендеринг\ndocument.getElementById('app').innerHTML = '<p>Updated</p>';\n// Браузер должен пересчитать DOM и CSSOM\n\n// Асинхронный JS не блокирует\nfetch('/api/data').then(r => r.json()).then(data => {\n // Обновляем когда готово\n document.getElementById('app').innerHTML = data.html;\n});\n```\n\n**Event Loop:**\n\n```\nCall Stack: console.log('start')\nMacro Task Queue: setTimeout callback\nMicro Task Queue: Promise.then\n\nПорядок выполнения:\n1. Все синхронный код (Call Stack)\n2. Все Promise.then (Micro Task)\n3. Следующий setTimeout (Macro Task)\n4. Micro Task Queue снова\n```\n\n### Шаг 12: Paint и Composite\n\n#### Layout (Reflow)\n\n```javascript\n// Читаем размеры - браузер должен пересчитать layout\nconst width = element.offsetWidth; // REFLOW!\nconst height = element.offsetHeight; // REFLOW!\n```\n\n**Дорого!** Избегай batch операций:\n\n```javascript\n// Плохо\nfor (let i = 0; i < 1000; i++) {\n element.style.left = i + 'px'; // 1000 reflows!\n}\n\n// Хорошо\nelement.style.left = '500px'; // 1 reflow\n```\n\n#### Paint (перерисовка)\n\n```\nРедактируем пиксели на экране:\n\nCSS свойства которые вызывают Paint:\n- background-color\n- border\n- text\n- shadow\n\nCSS свойства которые НЕ вызывают Paint:\n- transform (только Composite)\n- opacity (только Composite)\n```\n\n#### Composite\n\nЕсли используешь transform - это только Composite операция:\n\n```javascript\n// Быстро: нет Paint, только Composite\nelement.style.transform = 'translateX(100px)';\n\n// Медленно: Paint + Composite\nelement.style.left = '100px';\n```\n\n### Core Web Vitals: когда страница \"готова\"\n\n```\nFCP (First Contentful Paint) - когда первый контент видален\n |\n v\nLCP (Largest Contentful Paint) - когда основной контент видален\n |\n v\nCLS (Cumulative Layout Shift) - стабильность макета\n |\n v\nFID (First Input Delay) - отклик на действие пользователя\n```\n\n### Полный timeline пример\n\n```\n0ms - Пользователь кликает на ссылку\n50ms - DNS lookup завершён\n100ms - TCP handshake завершён\n150ms - TLS handshake завершён\n200ms - HTML начал загружаться\n500ms - HTML загружен, парсинг начался\n600ms - CSS загружен\n700ms - DOM парсинг завершён (FCP - First Contentful Paint)\n800ms - JS загружен и выполняется\n900ms - JS завершил инициализацию\n1000ms - Страница полностью готова (LCP)\n1200ms - All Resources loaded\n```\n\n### Как измерить это\n\n#### Chrome DevTools\n\n```javascript\n// Network tab показывает все загруженные ресурсы\n// Performance tab показывает timeline\n```\n\n#### Performance API\n\n```javascript\n// Измерить время загрузки\nwindow.addEventListener('load', () => {\n const perf = performance.timing;\n console.log('DNS время:', perf.domainLookupEnd - perf.domainLookupStart);\n console.log('TCP время:', perf.connectEnd - perf.connectStart);\n console.log('Request время:', perf.responseStart - perf.requestStart);\n console.log('DOM парсинг:', perf.domContentLoadedEventEnd - perf.domLoading);\n console.log('Total время:', perf.loadEventEnd - perf.navigationStart);\n});\n```\n\n### Оптимизация загрузки\n\n```html\n<!-- 1. Асинхронный JS -->\n<script src=\"/app.js\" async></script>\n\n<!-- 2. Отложенный JS (выполнится после парсинга) -->\n<script src=\"/app.js\" defer></script>\n\n<!-- 3. Предварительная загрузка ресурсов -->\n<link rel=\"preload\" href=\"/critical.css\" as=\"style\" />\n<link rel=\"preload\" href=\"/font.woff2\" as=\"font\" crossorigin />\n\n<!-- 4. DNS prefetch для внешних ресурсов -->\n<link rel=\"dns-prefetch\" href=\"//cdn.example.com\" />\n\n<!-- 5. Ленивая загрузка изображений -->\n<img src=\"image.jpg\" loading=\"lazy\" />\n```\n\n### Вывод\n\nПолный цикл загрузки страницы:\n\n1. **Сеть** (DNS, TCP, TLS) - 50-500 мс\n2. **Загрузка HTML** - зависит от размера и сервера\n3. **Парсинг HTML** - находит CSS и JS\n4. **Загрузка ресурсов** - параллельно\n5. **Построение DOM и CSSOM** - из HTML и CSS\n6. **Выполнение JS** - может изменить DOM\n7. **Рендеринг** - Layout, Paint, Composite\n8. **Страница готова** - видна пользователю\n\nЧтобы оптимизировать загрузку:\n- Минимизируй блокирующие ресурсы\n- Используй async/defer для JS\n- Оптимизируй изображения\n- Кешируй ресурсы\n- Используй CDN","dateCreated":"2026-04-02T22:25:03.167533","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}</script><script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"PrepBro","item":"https://prepbro.ru/"},{"@type":"ListItem","position":2,"name":"Frontend","item":"https://prepbro.ru/professions/frontend/questions"},{"@type":"ListItem","position":3,"name":"Вопросы","item":"https://prepbro.ru/professions/frontend/questions"}]}</script><header class="sticky top-0 z-50 w-full border-b border-border-primary bg-white"><div class="container mx-auto flex h-16 items-center justify-between px-4"><button class="md:hidden p-2 -ml-2" aria-expanded="false" aria-label="Открыть меню"><svg class="h-6 w-6 text-content-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16"></path></svg></button><a class="text-xl absolute left-1/2 -translate-x-1/2 md:static md:translate-x-0" href="/"><span class="font-black text-content-primary">Prep</span><span class="font-black text-primary-500">Bro</span></a><nav class="hidden md:flex items-center gap-6" aria-label="Основная навигация"><a class="text-sm font-medium text-content-primary hover:text-primary-600 transition-colors" href="/professions">Профессии</a><button class="rounded-lg px-5 py-2 text-sm font-semibold text-white bg-primary-600 hover:bg-primary-700 transition-colors">Войти</button></nav><div class="md:hidden w-10 h-10" aria-hidden="true"></div></div><div class="md:hidden"><nav class="fixed inset-y-0 left-0 z-50 w-72 bg-white shadow-xl overflow-y-auto flex flex-col transition-transform duration-300 -translate-x-full" aria-label="Мобильная навигация" aria-hidden="true"><div class="flex h-16 shrink-0 items-center justify-between px-4 border-b border-border-primary"><a class="text-xl" href="/"><span class="font-black text-content-primary">Prep</span><span class="font-black text-primary-500">Bro</span></a><button class="p-2" aria-label="Закрыть панель навигации"><svg class="h-6 w-6 text-content-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button></div><div class="flex-1 px-3 py-4"><a class="flex items-center rounded-lg px-3 py-2 text-sm text-content-primary hover:bg-surface-tertiary transition-colors" href="/professions">Профессии</a><div class="border-t border-border-primary pt-4 mt-4"><button class="w-full rounded-lg px-3 py-2 text-sm font-semibold text-white bg-primary-600 hover:bg-primary-700 transition-colors">Войти</button></div></div></nav></div></header><main class="container mx-auto px-4 py-8 max-w-4xl"><div class="mb-6"><nav class="flex items-center gap-1.5 text-sm text-content-secondary" aria-label="Навигация"><span class="flex items-center gap-1.5"><a class="hover:text-link transition-colors" href="/">PrepBro</a></span><span class="flex items-center gap-1.5"><span class="text-content-disabled">/</span><a class="hover:text-link transition-colors" href="/professions/frontend/questions">Frontend</a></span><span class="flex items-center gap-1.5"><span class="text-content-disabled">/</span><a class="hover:text-link transition-colors" href="/professions/frontend/questions">Вопросы</a></span><span class="flex items-center gap-1.5"><span class="text-content-disabled">/</span><span class="text-content-primary font-medium truncate max-w-[200px]">Как загружаются страницы в браузер?</span></span></nav></div><div><a class="inline-flex items-center gap-1 text-sm text-content-secondary hover:text-link transition-colors mb-4" href="/professions/frontend/questions">← Назад к вопросам</a><h1 class="text-2xl font-bold text-content-primary mb-4">Как загружаются страницы в браузер?</h1><div class="flex flex-wrap items-center gap-3 mb-4"><div class="flex items-center gap-2"><div class="h-5 w-5 rounded bg-surface-tertiary animate-pulse" data-testid="solved-checkbox-skeleton"></div><div class="h-4 w-14 rounded bg-surface-tertiary animate-pulse"></div></div><div class="flex items-center gap-2"><div class="h-5 w-5 rounded bg-surface-tertiary animate-pulse" data-testid="seen-checkbox-skeleton"></div><div class="h-4 w-32 rounded bg-surface-tertiary animate-pulse"></div></div><span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium" style="background:hsl(45, 62.5%, 84.5%);color:hsl(45, 70%, 25%)">2.0<!-- --> <!-- -->Middle</span><span class="rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-700" title="Частота на собеседованиях">🔥 <!-- -->19</span><span class="text-sm text-content-secondary">1<!-- --> комментариев</span></div><div class="flex flex-wrap gap-2 mb-4"><span class="rounded-full bg-surface-tertiary px-2.5 py-0.5 text-xs text-content-primary">#<!-- -->Браузер и сетевые технологии</span></div></div><div class="mt-6"><div class="rounded-lg border border-gray-200 bg-white p-4" data-testid="grade-voting-skeleton"><div class="h-4 w-32 rounded bg-surface-tertiary animate-pulse mb-3"></div><div class="flex gap-2"><div class="h-10 w-24 rounded-lg bg-surface-tertiary animate-pulse"></div><div class="h-10 w-24 rounded-lg bg-surface-tertiary animate-pulse"></div><div class="h-10 w-24 rounded-lg bg-surface-tertiary animate-pulse"></div></div></div></div><div class="mt-6"><button class="text-sm text-content-secondary hover:text-link transition-colors">Предложить правку</button><span hidden="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"></span></div><div class="mt-8"><div><div class="mb-4 flex items-center justify-between"><h2 class="text-lg font-semibold text-content-primary">Комментарии (<!-- -->1<!-- -->)</h2><div class="flex gap-1"><button class="rounded-lg px-3 py-1 text-sm transition-colors bg-primary-100 text-primary-700">По лайкам</button><button class="rounded-lg px-3 py-1 text-sm transition-colors text-content-secondary hover:bg-surface-tertiary">По дате</button></div></div><div class="divide-y divide-surface-tertiary"><div class="py-4"><div class="flex items-start gap-3"><div class="flex shrink-0 items-center justify-center rounded-full h-8 w-8 text-sm" style="background-color:#6366f130">🐱</div><div class="min-w-0 flex-1"><div class="flex items-center gap-2 mb-1"><span class="text-sm font-medium text-content-primary">claude-haiku-4.5</span><span class="rounded-full bg-primary-100 px-2 py-0.5 text-xs font-medium text-primary-700">PrepBro AI</span><span class="text-xs text-content-tertiary">2 апр. 2026 г.</span><span class="text-xs text-content-tertiary">(ред.)</span></div><p class="text-xs text-content-tertiary mb-2">Ответ сгенерирован нейросетью и может содержать ошибки</p><div><div class="mb-3 inline-flex rounded-lg bg-surface-tertiary p-1 gap-1"><button class="group relative rounded-md px-3 py-1.5 text-sm transition-colors text-content-tertiary hover:text-content-secondary">Code<span class="pointer-events-none invisible absolute bottom-full left-1/2 z-10 mb-2 w-[220px] -translate-x-1/2 whitespace-normal rounded-md bg-[#111] p-1.5 text-center text-xs leading-snug text-white opacity-0 transition-opacity group-hover:visible group-hover:opacity-100">Без форматирования, вывести как код<span class="absolute top-full left-1/2 -translate-x-1/2 border-[5px] border-transparent border-t-[#111]"></span></span></button><button class="group relative rounded-md px-3 py-1.5 text-sm transition-colors bg-white text-content-primary font-medium shadow-sm">Auto<span class="pointer-events-none invisible absolute bottom-full left-1/2 z-10 mb-2 w-[220px] -translate-x-1/2 whitespace-normal rounded-md bg-[#111] p-1.5 text-center text-xs leading-snug text-white opacity-0 transition-opacity group-hover:visible group-hover:opacity-100">Форматировать автоматически (помогает, если нейронка плохо отформатировала текст)<span class="absolute top-full left-1/2 -translate-x-1/2 border-[5px] border-transparent border-t-[#111]"></span></span></button><button class="group relative rounded-md px-3 py-1.5 text-sm transition-colors text-content-tertiary hover:text-content-secondary">Markdown<span class="pointer-events-none invisible absolute bottom-full left-1/2 z-10 mb-2 w-[220px] -translate-x-1/2 whitespace-normal rounded-md bg-[#111] p-1.5 text-center text-xs leading-snug text-white opacity-0 transition-opacity group-hover:visible group-hover:opacity-100">Визуализировать как Markdown<span class="absolute top-full left-1/2 -translate-x-1/2 border-[5px] border-transparent border-t-[#111]"></span></span></button></div><div><h2 class="text-lg font-semibold text-content-primary mt-5 mb-2">Как загружаются страницы в браузер</h2> <p class="text-sm text-content-primary mb-3 leading-relaxed">Это один из самых фундаментальных процессов в веб-разработке. Понимание этого критично для оптимизации производительности и отладки проблем.</p> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Полный цикл загрузки страницы</h3> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">1. Пользователь вводит URL | v 2. DNS lookup (поиск IP адреса) | v 3. TCP handshake (соединение) | v 4. TLS handshake (HTTPS) | v 5. HTTP запрос отправляется | v 6. Сервер обрабатывает запрос | v 7. Ответ (HTML) загружается | v 8. Браузер парсит HTML | v 9. Загружаются ресурсы (CSS, JS, изображения) | v 10. Рендеринг (построение DOM, применение стилей) | v 11. Выполнение JavaScript | v 12. Paint (отрисовка пикселей) | v 13. Страница видна пользователю </code></pre> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Шаг 1-4: Сетевая часть</h3> <h4>DNS Lookup (50-300 мс)</h4> <p class="text-sm text-content-primary mb-3 leading-relaxed"><strong class="font-semibold text-content-primary">Domain Name System</strong> преобразует доменное имя в IP адрес:</p> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">Вход: example.com Процесс: 1. Браузер проверяет кеш (обычно есть) 2. Если нет - запрашивает рекурсивный резолвер (ISP) 3. Резолвер запрашивает Root nameserver 4. Root отправляет на TLD nameserver (.com) 5. TLD отправляет на Authoritative nameserver 6. Authoritative возвращает IP: 93.184.216.34 Выход: 93.184.216.34 </code></pre> <p class="text-sm text-content-primary mb-3 leading-relaxed"><strong class="font-semibold text-content-primary">Оптимизация:</strong></p> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-html" node="[object Object]"><span class="hljs-comment"><!-- Подскажи браузеру заранее) <link rel="dns-prefetch" href="//cdn.example.com" /> <link rel="preconnect" href="//api.example.com" /> </span></code></pre> <h4>TCP Handshake (50-100 мс)</h4> <p class="text-sm text-content-primary mb-3 leading-relaxed">Установление соединения с сервером (three-way handshake):</p> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">Клиент -> Сервер: SYN (Can we talk?) Сервер -> Клиент: SYN-ACK (Yes) Клиент -> Сервер: ACK (Great) Соединение установлено! </code></pre> <h4>TLS Handshake для HTTPS (100-300 мс)</h4> <p class="text-sm text-content-primary mb-3 leading-relaxed">Зашифрованное соединение (SSL/TLS):</p> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">Клиент -> Сервер: ClientHello (поддерживаемые шифры) Сервер -> Клиент: ServerHello + Certificate Клиент проверяет сертификат Оба согласуют ключи шифрования Соединение зашифровано </code></pre> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Шаг 5-7: HTTP запрос и ответ</h3> <h4>HTTP запрос</h4> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-http" node="[object Object]">GET / HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0... Accept: text/html Referer: https://google.com Cookie: sessionId=xyz </code></pre> <p class="text-sm text-content-primary mb-3 leading-relaxed">Браузер отправляет это на сервер.</p> <h4>Ответ сервера</h4> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-http" node="[object Object]">HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 1234 Cache-Control: max-age=3600 Set-Cookie: newSessionId=abc <!DOCTYPE html> <html> <head>...</head> <body>...</body> </html> </code></pre> <p class="text-sm text-content-primary mb-3 leading-relaxed"><strong class="font-semibold text-content-primary">Время:</strong> зависит от сервера и расстояния (latency)</p> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Шаг 8-9: Парсинг HTML и загрузка ресурсов</h3> <p class="text-sm text-content-primary mb-3 leading-relaxed">Это критическая часть для производительности:</p> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-html" node="[object Object]"><span class="hljs-meta"><!DOCTYPE <span class="hljs-keyword">html</span>></span> <span class="hljs-tag"><<span class="hljs-name">html</span>></span> <span class="hljs-tag"><<span class="hljs-name">head</span>></span> <span class="hljs-comment"><!-- Блокирующие ресурсы --></span> <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /></span> <span class="hljs-tag"><<span class="hljs-name">title</span>></span>Моя страница<span class="hljs-tag"></<span class="hljs-name">title</span>></span> <span class="hljs-comment"><!-- CSS блокирует рендеринг --></span> <span class="hljs-tag"><<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/style.css"</span> /></span> <span class="hljs-tag"><<span class="hljs-name">style</span>></span><span class="css"><span class="hljs-selector-tag">body</span> { <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>; }</span><span class="hljs-tag"></<span class="hljs-name">style</span>></span> <span class="hljs-tag"></<span class="hljs-name">head</span>></span> <span class="hljs-tag"><<span class="hljs-name">body</span>></span> <span class="hljs-tag"><<span class="hljs-name">h1</span>></span>Заголовок<span class="hljs-tag"></<span class="hljs-name">h1</span>></span> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/image.jpg"</span> /></span> <span class="hljs-tag"><<span class="hljs-name">p</span>></span>Содержимое<span class="hljs-tag"></<span class="hljs-name">p</span>></span> <span class="hljs-comment"><!-- JS блокирует парсинг --></span> <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/app.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> <span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Inline script'</span>); </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> <span class="hljs-tag"></<span class="hljs-name">body</span>></span> <span class="hljs-tag"></<span class="hljs-name">html</span>></span> </code></pre> <h4>Как браузер парсит:</h4> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">1. Браузер читает HTML построчно | v 2. <meta charset> - установить кодировку | v 3. <title> - установить название вкладки | v 4. <link rel="stylesheet"> СТОП! ЗАГРУЗИТЬ CSS Парсинг приостановлен, ждём CSS | v 5. CSS загружен - продолжить | v 6. Парсим <body> - <h1> добавляется в DOM - <img> отправляем запрос на изображение - <p> добавляется в DOM | v 7. <script src=""> СТОП! ЗАГРУЗИТЬ И ВЫПОЛНИТЬ JS Парсинг приостановлен Сеть загружает JS V8 выполняет JS | v 8. Inline <script> выполняется | v 9. Парсинг завершён </code></pre> <p class="text-sm text-content-primary mb-3 leading-relaxed"><strong class="font-semibold text-content-primary">Оптимизация:</strong></p> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-html" node="[object Object]"><span class="hljs-comment"><!-- Неблокирующий CSS --></span> <span class="hljs-tag"><<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/style.css"</span> /></span> <span class="hljs-comment"><!-- Неблокирующий JS (внизу страницы) --></span> <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/app.js"</span> <span class="hljs-attr">defer</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> <span class="hljs-comment"><!-- Или async для независимого JS --></span> <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/analytics.js"</span> <span class="hljs-attr">async</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> </code></pre> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Шаг 10: Рендеринг (Rendering Pipeline)</h3> <h4>Построение DOM</h4> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">HTML <html> <body> <div id="app">Hello</div> </body> </html> | v DOM Tree html | body | div#app (text: "Hello") </code></pre> <h4>Построение CSSOM</h4> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">CSS body { margin: 0; } #app { color: blue; } | v CSSOM Tree body { margin: 0 } | #app { color: blue; margin: 0 (наследовано) } </code></pre> <h4>Создание Render Tree</h4> <p class="text-sm text-content-primary mb-3 leading-relaxed">Объединение DOM и CSSOM:</p> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">DOM + CSSOM | v Render Tree (только видимые элементы) body { margin: 0 } | div#app { color: blue, margin: 0 } (display: none элементы не включаются) </code></pre> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Шаг 11: Выполнение JavaScript</h3> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-javascript" node="[object Object]"><span class="hljs-comment">// Синхронный JS блокирует рендеринг</span> <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">'app'</span>).<span class="hljs-property">innerHTML</span> = <span class="hljs-string">'<p>Updated</p>'</span>; <span class="hljs-comment">// Браузер должен пересчитать DOM и CSSOM</span> <span class="hljs-comment">// Асинхронный JS не блокирует</span> <span class="hljs-title function_">fetch</span>(<span class="hljs-string">'/api/data'</span>).<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">r</span> =></span> r.<span class="hljs-title function_">json</span>()).<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">data</span> =></span> { <span class="hljs-comment">// Обновляем когда готово</span> <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">'app'</span>).<span class="hljs-property">innerHTML</span> = data.<span class="hljs-property">html</span>; }); </code></pre> <p class="text-sm text-content-primary mb-3 leading-relaxed"><strong class="font-semibold text-content-primary">Event Loop:</strong></p> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">Call Stack: console.log('start') Macro Task Queue: setTimeout callback Micro Task Queue: Promise.then Порядок выполнения: 1. Все синхронный код (Call Stack) 2. Все Promise.then (Micro Task) 3. Следующий setTimeout (Macro Task) 4. Micro Task Queue снова </code></pre> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Шаг 12: Paint и Composite</h3> <h4>Layout (Reflow)</h4> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-javascript" node="[object Object]"><span class="hljs-comment">// Читаем размеры - браузер должен пересчитать layout</span> <span class="hljs-keyword">const</span> width = element.<span class="hljs-property">offsetWidth</span>; <span class="hljs-comment">// REFLOW!</span> <span class="hljs-keyword">const</span> height = element.<span class="hljs-property">offsetHeight</span>; <span class="hljs-comment">// REFLOW!</span> </code></pre> <p class="text-sm text-content-primary mb-3 leading-relaxed"><strong class="font-semibold text-content-primary">Дорого!</strong> Избегай batch операций:</p> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-javascript" node="[object Object]"><span class="hljs-comment">// Плохо</span> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">1000</span>; i++) { element.<span class="hljs-property">style</span>.<span class="hljs-property">left</span> = i + <span class="hljs-string">'px'</span>; <span class="hljs-comment">// 1000 reflows!</span> } <span class="hljs-comment">// Хорошо</span> element.<span class="hljs-property">style</span>.<span class="hljs-property">left</span> = <span class="hljs-string">'500px'</span>; <span class="hljs-comment">// 1 reflow</span> </code></pre> <h4>Paint (перерисовка)</h4> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">Редактируем пиксели на экране: CSS свойства которые вызывают Paint: - background-color - border - text - shadow CSS свойства которые НЕ вызывают Paint: - transform (только Composite) - opacity (только Composite) </code></pre> <h4>Composite</h4> <p class="text-sm text-content-primary mb-3 leading-relaxed">Если используешь transform - это только Composite операция:</p> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-javascript" node="[object Object]"><span class="hljs-comment">// Быстро: нет Paint, только Composite</span> element.<span class="hljs-property">style</span>.<span class="hljs-property">transform</span> = <span class="hljs-string">'translateX(100px)'</span>; <span class="hljs-comment">// Медленно: Paint + Composite</span> element.<span class="hljs-property">style</span>.<span class="hljs-property">left</span> = <span class="hljs-string">'100px'</span>; </code></pre> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Core Web Vitals: когда страница "готова"</h3> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">FCP (First Contentful Paint) - когда первый контент видален | v LCP (Largest Contentful Paint) - когда основной контент видален | v CLS (Cumulative Layout Shift) - стабильность макета | v FID (First Input Delay) - отклик на действие пользователя </code></pre> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Полный timeline пример</h3> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="rounded bg-surface-tertiary px-1.5 py-0.5 text-xs font-mono text-link-hover" node="[object Object]">0ms - Пользователь кликает на ссылку 50ms - DNS lookup завершён 100ms - TCP handshake завершён 150ms - TLS handshake завершён 200ms - HTML начал загружаться 500ms - HTML загружен, парсинг начался 600ms - CSS загружен 700ms - DOM парсинг завершён (FCP - First Contentful Paint) 800ms - JS загружен и выполняется 900ms - JS завершил инициализацию 1000ms - Страница полностью готова (LCP) 1200ms - All Resources loaded </code></pre> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Как измерить это</h3> <h4>Chrome DevTools</h4> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-javascript" node="[object Object]"><span class="hljs-comment">// Network tab показывает все загруженные ресурсы</span> <span class="hljs-comment">// Performance tab показывает timeline</span> </code></pre> <h4>Performance API</h4> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-javascript" node="[object Object]"><span class="hljs-comment">// Измерить время загрузки</span> <span class="hljs-variable language_">window</span>.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">'load'</span>, <span class="hljs-function">() =></span> { <span class="hljs-keyword">const</span> perf = performance.<span class="hljs-property">timing</span>; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'DNS время:'</span>, perf.<span class="hljs-property">domainLookupEnd</span> - perf.<span class="hljs-property">domainLookupStart</span>); <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'TCP время:'</span>, perf.<span class="hljs-property">connectEnd</span> - perf.<span class="hljs-property">connectStart</span>); <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Request время:'</span>, perf.<span class="hljs-property">responseStart</span> - perf.<span class="hljs-property">requestStart</span>); <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'DOM парсинг:'</span>, perf.<span class="hljs-property">domContentLoadedEventEnd</span> - perf.<span class="hljs-property">domLoading</span>); <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Total время:'</span>, perf.<span class="hljs-property">loadEventEnd</span> - perf.<span class="hljs-property">navigationStart</span>); }); </code></pre> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Оптимизация загрузки</h3> <pre class="rounded-lg bg-surface-dark p-4 mb-3 overflow-x-auto text-xs leading-relaxed"><code class="text-xs hljs language-html" node="[object Object]"><span class="hljs-comment"><!-- 1. Асинхронный JS --></span> <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/app.js"</span> <span class="hljs-attr">async</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> <span class="hljs-comment"><!-- 2. Отложенный JS (выполнится после парсинга) --></span> <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/app.js"</span> <span class="hljs-attr">defer</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> <span class="hljs-comment"><!-- 3. Предварительная загрузка ресурсов --></span> <span class="hljs-tag"><<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"preload"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/critical.css"</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"style"</span> /></span> <span class="hljs-tag"><<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"preload"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/font.woff2"</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"font"</span> <span class="hljs-attr">crossorigin</span> /></span> <span class="hljs-comment"><!-- 4. DNS prefetch для внешних ресурсов --></span> <span class="hljs-tag"><<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"dns-prefetch"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"//cdn.example.com"</span> /></span> <span class="hljs-comment"><!-- 5. Ленивая загрузка изображений --></span> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"image.jpg"</span> <span class="hljs-attr">loading</span>=<span class="hljs-string">"lazy"</span> /></span> </code></pre> <h3 class="text-base font-semibold text-content-primary mt-4 mb-2">Вывод</h3> <p class="text-sm text-content-primary mb-3 leading-relaxed">Полный цикл загрузки страницы:</p> <ol class="list-decimal list-inside text-sm text-content-primary mb-3 space-y-1"> <li class="text-sm text-content-primary"><strong class="font-semibold text-content-primary">Сеть</strong> (DNS, TCP, TLS) - 50-500 мс</li> <li class="text-sm text-content-primary"><strong class="font-semibold text-content-primary">Загрузка HTML</strong> - зависит от размера и сервера</li> <li class="text-sm text-content-primary"><strong class="font-semibold text-content-primary">Парсинг HTML</strong> - находит CSS и JS</li> <li class="text-sm text-content-primary"><strong class="font-semibold text-content-primary">Загрузка ресурсов</strong> - параллельно</li> <li class="text-sm text-content-primary"><strong class="font-semibold text-content-primary">Построение DOM и CSSOM</strong> - из HTML и CSS</li> <li class="text-sm text-content-primary"><strong class="font-semibold text-content-primary">Выполнение JS</strong> - может изменить DOM</li> <li class="text-sm text-content-primary"><strong class="font-semibold text-content-primary">Рендеринг</strong> - Layout, Paint, Composite</li> <li class="text-sm text-content-primary"><strong class="font-semibold text-content-primary">Страница готова</strong> - видна пользователю</li> </ol> <p class="text-sm text-content-primary mb-3 leading-relaxed">Чтобы оптимизировать загрузку:</p> <ul class="list-disc list-inside text-sm text-content-primary mb-3 space-y-1"> <li class="text-sm text-content-primary">Минимизируй блокирующие ресурсы</li> <li class="text-sm text-content-primary">Используй async/defer для JS</li> <li class="text-sm text-content-primary">Оптимизируй изображения</li> <li class="text-sm text-content-primary">Кешируй ресурсы</li> <li class="text-sm text-content-primary">Используй CDN</li> </ul></div></div><div class="mt-2 flex items-center gap-4"><button class="flex items-center gap-1 text-xs transition-colors text-content-tertiary hover:text-red-500">♡<!-- --> </button><button class="text-xs text-content-tertiary hover:text-link transition-colors">Ответить</button><button class="text-xs text-link hover:underline transition-colors">Свернуть</button></div></div></div><span hidden="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"></span><span hidden="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"></span></div></div><div class="mt-6"><div class="rounded-lg border border-border-primary bg-white p-4"><textarea readOnly="" placeholder="Войдите, чтобы оставить комментарий" class="w-full resize-none rounded-lg border border-border-primary bg-surface-secondary p-3 text-sm text-content-tertiary placeholder:text-content-tertiary cursor-pointer" rows="3"></textarea><div class="mt-2 flex justify-end"><button disabled="" class="rounded-lg bg-surface-muted px-4 py-2 text-sm font-medium text-white cursor-not-allowed">Отправить</button></div></div></div></div></div></main><footer class="border-t border-border-primary bg-surface-secondary py-8"><div class="container mx-auto px-4 text-center"><div class="flex flex-col items-center gap-4 sm:flex-row sm:justify-between"><p class="text-sm text-content-primary">© 2026 PrepBro. Все права защищены.</p><div class="flex gap-4"><a href="https://t.me/prepbro_bot" target="_blank" rel="noopener noreferrer" class="text-sm text-content-primary hover:text-primary-600 transition-colors">Telegram-бот</a></div></div></div></footer></div><!--$?--><template id="B:1"></template><!--/$--><span hidden="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"></span><button aria-label="Наверх" class="hidden lg:fixed lg:flex bottom-8 right-8 z-40 h-12 w-12 items-center justify-center rounded-full bg-primary-600 text-white shadow-lg hover:bg-primary-700 transition-opacity duration-300 opacity-0 pointer-events-none"><svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M5 15l7-7 7 7"></path></svg></button><script>requestAnimationFrame(function(){$RT=performance.now()});</script><script src="/_next/static/chunks/5ffdb00edfe2eeb6.js" id="_R_" async=""></script><title>Как загружаются страницы в браузер? | PrepBro