Вы вводите адрес, нажимаете Enter — и через мгновение видите страницу. За это время браузер определяет, куда обращаться, договаривается о соединении, получает несколько видов ресурсов, строит, рассчитывает, параллельно загружает файлы и использует результаты прошлых посещений. Превращает всё это в пиксели и пользователь получает итоговую картинку.
Как это работает
В упрощённом виде происходит следующее:
- браузер разбирает URL;
- проверяет кэш и локальные правила;
- находит сетевой адрес через DNS;
- устанавливает соединение;
- для HTTPS создаёт защищённый канал;
- отправляет HTTP-запрос;
- получает ответ и начинает разбирать HTML;
- обнаруживает и загружает связанные ресурсы;
- строит DOM и CSSOM;
- формирует дерево отображения;
- рассчитывает геометрию;
- рисует и объединяет слои;
- выполняет JavaScript и обновляет интерфейс.
Теперь разберём этот путь подробнее.
1. Браузер разбирает адрес
URL https://example.com/catalog/?sort=new содержит несколько частей:
https— схема, определяющая способ обращения;example.com— доменное имя;/catalog/— путь к ресурсу;sort=new— параметры запроса.
Сначала браузер проверяет, является ли введённая строка адресом. Если это обычные слова, он может передать их поисковой системе. Для известного URL применяются правила безопасности, перенаправления и сохранённые сведения о домене. Использование сохранённых данных позволяет сократить время загрузки.
2. Проверяется кэш
Некоторые данные уже могут находиться на устройстве:
- результат DNS-запроса;
- ранее загруженный HTML;
- стили, сценарии, шрифты и изображения;
- инструкции service worker веб-приложения;
- сведения, позволяющие быстрее возобновить защищённое соединение.
Использование кэша не означает, что браузер показывает старую сохранённую ранее копию. Сервер передаёт правила свежести и проверки. В зависимости от установленных правил для конкретного ресурса он может использоваться сразу или загружаться заново.
3. DNS находит адрес сервера
Человек вводит доменное имя и сетевые пакеты доставляются по IP-адресам. DNS сопоставляет доменное имя с IP-адресом и после этого браузер устанавливает соединение с сервером и загружает сайт. Весь этот путь проходит незаметно для пользователя.
Ответ может найтись в кэше браузера, операционной системы, роутера или DNS-резолвера. Если записи нет, резолвер проходит иерархию DNS и получает адрес, связанный с нужным именем.
Один домен может возвращать несколько адресов. Сервис способен направить пользователя к подходящему узлу или CDN, чтобы сократить расстояние и распределить нагрузку.
DNS сообщает, куда обращаться, но не гарантирует, что веб-сервер исправен и вернёт нужную страницу. Если сказать простым языком — это удобный «переводчик» для сети, который решает задачу преобразования удобочитаемых имён в машинные адреса.
4. Устанавливается транспортное соединение
Дальнейшие детали зависят от версии HTTP и сетевой среды.
Для HTTP/1.1 и HTTP/2 обычно используется TCP. Клиент и сервер устанавливают соединение, которое обеспечивает упорядоченную и надёжную передачу потока байтов.
HTTP/3 работает поверх QUIC, использующего UDP как базовый транспорт и реализующего необходимые механизмы доставки и шифрования иначе. Проще говоря: до веб-запроса стороны должны создать рабочий канал обмена.
Задержка зависит от расстояния, качества сети и числа необходимых сетевых обменов. Поэтому сервер в другом регионе может начать отвечать позже, даже если обрабатывает запрос мгновенно.
5. HTTPS защищает соединение
При HTTPS браузер и сервер выполняют TLS-согласование. Сервер показывает сертификат, браузер проверяет доменное имя, срок действия и цепочку доверия, стороны выбирают параметры защиты и получают ключи сеанса.
После этого данные между участниками соединения шифруются и защищаются от незаметного изменения в пути.
HTTPS не доказывает, что содержание сайта правдиво или что приложение не имеет уязвимостей. Он подтверждает защищённое соединение с владельцем сертификата для указанного имени.
6. Отправляется HTTP-запрос
Браузер формирует запрос примерно такого смысла:
Получить ресурс
/catalog/?sort=newс доменаexample.com.
В нём находятся метод, путь, заголовки и иногда тело. Заголовки могут сообщать о поддерживаемых форматах, языке, кэше, авторизации и источнике перехода.
Сервер или цепочка промежуточных компонентов принимает запрос. Перед приложением могут находиться CDN, балансировщик, reverse proxy, кэш и защитный фильтр.
7. Сервер готовит ответ
Ответ включает:
- код состояния;
- заголовки;
- тело ресурса.
Код 200 означает успешный ответ. 301 или 308 сообщает о постоянном перенаправлении. 404 — что ресурс не найден. 500 — что сервер столкнулся с ошибкой.
HTML может быть готовым файлом или результатом работы приложения. Сервер способен обратиться к базе данных, проверить сессию, собрать шаблон и вызвать другие сервисы. Поэтому задержка «ответа сервера» иногда скрывает целую внутреннюю цепочку.
8. HTML приходит потоком
Браузеру не обязательно ждать весь документ. Получив первые части HTML, он начинает разбор.
Текст превращается в токены, а затем в узлы дерева DOM. Вложенность элементов определяет отношения между ними. Заголовок, абзац и ссылка становятся объектами, к которым могут обращаться стили, JavaScript и технологии доступности.
HTML-парсер следует формальным правилам и умеет восстанавливать многие ошибки разметки. Это делает Web устойчивым к несовершенным документам, но не превращает небрежную структуру в хорошую семантику.
9. Обнаруживаются дополнительные ресурсы
В HTML встречаются ссылки на:
- CSS-файлы;
- JavaScript;
- изображения;
- шрифты;
- видео и аудио;
- встроенные документы;
- данные для предварительной загрузки.
Браузер ставит запросы в очередь и определяет приоритет. Отдельный предварительный сканер может находить ресурсы раньше, чем основной парсер дойдёт до их обработки.
Количество файлов не равно количеству последовательных ожиданий: современные соединения позволяют передавать несколько ресурсов эффективнее. Но каждый лишний байт всё равно нужно получить, разобрать и иногда выполнить.
10. CSS превращается в CSSOM
Браузер разбирает правила стилей и строит CSS Object Model. Затем каскад, наследование и селекторы определяют вычисленные значения для элементов.
CSS влияет на то, как выглядит и располагается содержимое страницы, поэтому браузеру нужна информация о стилях для корректного отображения.
11. JavaScript может изменить ход загрузки
Обычный синхронный <script> во время разбора HTML может приостановить парсер: сценарий способен изменить документ, поэтому браузер должен выполнить его в нужной точке.
Атрибуты defer и async, модульные сценарии и загрузка по требованию позволяют управлять поведением. Но универсального правила «весь JavaScript сделать асинхронным» нет: порядок и зависимости имеют значение.
После запуска JavaScript может:
- добавить или удалить элементы;
- изменить классы и стили;
- запросить новые данные;
- зарегистрировать обработчики событий;
- обновить интерфейс;
- начать вычисление на основном потоке или в worker.
Долгое выполнение кода может задержать реакцию страницы, даже если файлы уже загружены.
12. Создаётся дерево отображения
DOM описывает документ, CSSOM — стили. На их основе браузер определяет, какие узлы нужно показать и с какими вычисленными свойствами.
Элементы из <head> и узлы с display: none не занимают место в отображаемом дереве. Элемент с visibility: hidden остаётся частью компоновки, хотя визуально скрыт.
Параллельно браузер формирует дерево доступности, через которое вспомогательные технологии понимают роли, названия и отношения элементов.
13. Layout рассчитывает геометрию
На этапе layout браузер определяет размеры и координаты видимых блоков. Проценты, гибкие сетки, размеры окна, шрифты и содержимое превращаются в конкретное расположение.
Если поздно загруженное изображение не имеет заранее заданных размеров, окружающий текст может сдвинуться. Подобные изменения ухудшают визуальную стабильность.
Изменение DOM или стиля иногда требует повторного расчёта части страницы. Частые чтения и изменения геометрии внутри сценария могут создавать заметные задержки.
14. Paint рисует элементы
Браузер превращает рассчитанные блоки в команды рисования: фон, текст, рамки, тени и изображения.
Некоторые части оказываются на отдельных слоях. На этапе compositing слои объединяются в итоговый кадр. Это позволяет, например, перемещать отдельный слой без полной перерисовки страницы, но чрезмерное число слоёв тоже расходует память.
Монитор начинает показывает готовый кадр даже если страница ещё продолжает загружать данные и изменяться.
Когда страница считается загруженной
Техническое событие load не обязательно совпадает с ощущением готовности. И наоборот: страница может стать полезной до загрузки второстепенной аналитики или изображения которое подгружается после прокручивания страницы.
Где чаще всего теряется время
Задержка может появиться на любом уровне:
- медленный DNS;
- большое сетевое расстояние;
- долгий ответ приложения или базы данных;
- отсутствие кэширования;
- тяжёлые изображения и шрифты;
- блокирующие стили и сценарии;
- слишком большой JavaScript;
- долгие задачи на основном потоке;
- повторные расчёты расположения;
- ресурсы сторонних сервисов;
- загрузка данных только после выполнения большого приложения.
Поэтому совет «ускорить сервер» или «сжать картинки» не является универсальным. Сначала измеряют конкретный маршрут.
Что меняется при повторном посещении
Браузер уже знает часть DNS-ответов, может переиспользовать соединение и хранить ресурсы в кэше. Service worker способен вернуть локальную копию или собрать ответ по правилам приложения.
Именно поэтому страница может быстро открываться у разработчика и медленно у нового посетителя. Проверять нужно как повторную, так и первую загрузку, на мобильной сети и менее мощном устройстве.
Главное
После нажатия Enter браузер не «скачивает сайт» одним файлом. Он проходит несколько уровней:
- находит адрес;
- создаёт сетевое и защищённое соединение;
- обменивается HTTP-сообщениями;
- получает HTML и связанные ресурсы;
- строит DOM и CSSOM;
- рассчитывает расположение;
- рисует и объединяет слои;
- выполняет сценарии и реагирует на изменения.
Скорость загрузки страницы зависит от работы всей цепочки. Чтобы улучшить её, нужно определить, какой этап мешает пользователю увидеть содержимое или выполнить действие, а не просто сделать все файлы немного меньше.