Это, наверное, самый полный ответ, который вы когда-либо видели

Возможно, вы видели этот вопрос во многих местах, но это не мешает ему быть очень популярным. Эта статья познакомит вас с некоторыми из них.

Модель процесса в браузере

Здесь мы берем репрезентативный браузер Chrome в качестве примера, и другие основные браузеры аналогичны.

Нажмите на три точки справа и выберите Дополнительные инструменты -> Диспетчер задач. Вы можете увидеть что-то похожее на картинку выше. Вы также можете использовать ярлык Shift + Esc, чтобы быстро открыть его.

Это модель процесса в браузере, позвольте мне объяснить это подробно:

  • Основной процесс в одном браузере: в основном отвечает за отображение интерфейса, взаимодействие с пользователем, управление дочерними процессами, хранение файлов и т. д.
  • Один процесс GPU: визуализирует весь внутренний пользовательский интерфейс, например веб-страницы, пользовательский интерфейс Chrome и т. д.
  • Один сетевой процесс: отвечает за загрузку всех сетевых ресурсов.
  • Несколько процессов расширения: отвечает за запуск расширения.
  • Несколько процессов рендеринга: в основном отвечает за преобразование HTML, CSS и JavaScript в интерактивные веб-страницы. В этом процессе работают как наборный движок Blink, так и движок V8. И каждый процесс рендеринга выполняется в песочнице для защиты ресурсов системы пользователя.

Ранние браузеры были однопроцессорными, то есть все функциональные модули браузера выполнялись в одном процессе. Это приводит к множеству проблем, таких как:

  • Когда происходит сбой веб-страницы или расширения, происходит сбой всего браузера.
  • Когда вредоносные скрипты внедряются в веб-страницы или расширения, могут возникнуть проблемы с безопасностью.
  • Если на веб-странице выполняется бесконечный цикл, все открытые страницы в браузере зависнут. Это обычная зависание в Windows :)

Поэтому текущий браузер использует многопроцессорную архитектуру. И веб-страницы, и расширения изолированы (что делает их неспособными затронуть систему пользователя). И каждая веб-страница и расширение являются независимыми процессами и не влияют друг на друга. Это решает указанные выше проблемы.

Что случилось?

Зная модель процесса браузера, мы можем приступить к ответу на этот вопрос.

На картинке выше весь процесс записи с Performance, выглядит очень долго. Я буду вырезать части, как я объясню, пожалуйста, обратите внимание на временную шкалу выше, чтобы соответствовать общему процессу.

Просто разделив процесс на два этапа:

Начальная ступень

На приведенном выше рисунке показан процесс навигации (от пользователя, инициирующего запрос URL, до момента, когда страница начинает анализироваться).

После того, как пользователь введет адрес в поле и нажмет Enter:

1. Браузер сначала определит, является ли входной контент URL-адресом, если нет, он будет объединен в URL-адрес поисковой системой по умолчанию. После этого, если исходная веб-страница привязана к событию beforeunload, оно вызовет всплывающее окно.

2. Только после нажатия кнопки «Подтвердить» можно перейти к следующему шагу. В этот момент процесс браузера отправляет запрос URL сетевому процессу через IPC. Тогда сетевой процесс сначала проверит, есть ли кэш в локальном кэше. Приоритет локального кеша — Service Worker, кэш памяти, кэш диска и кэш HTTP2 Push. Если он есть в наличии, он будет возвращен напрямую, без реального запроса.

3. Настоящим запросом является процесс HTTP-запроса, с которым мы знакомы. Первым шагом является разрешение DNS для получения IP-адреса службы. Если это HTTPS, необходимо установить TLS-соединение. Следующим шагом будет использование трехэтапного IP-подтверждения для установления TCP-соединения. После создания сетевой процесс формирует строку запроса (метод, URL, версия), заголовок запроса и тело запроса и отправляет их на сервер. После того, как сервер получает его, обработка завершается, и строка ответа (версия, код состояния, описание состояния), заголовок ответа и тело ответа генерируются и возвращаются клиенту.

4. После того как сетевой процесс его получает, он сначала анализирует код состояния и заголовок ответа. Если код состояния 301 или 302, то запрос будет снова объединен в соответствии с Location в заголовке ответа. Затем посмотрите заголовок ответа Content-type. Если это поток байтов, он будет отправлен на загрузку менеджеру загрузки. Если это HTML, он уведомит процесс браузера о подготовке процесса рендеринга.

5. Обычно браузеры создают процесс рендеринга для каждой веб-страницы. Но если это один и тот же сайт, его можно использовать повторно. Дождавшись его готовности, данные сетевого процесса перейдут через процесс браузера в процесс рендеринга. Когда передача завершена, браузер также обновляет внешний пользовательский интерфейс браузера. Например, статус блокировки безопасности HTTPS, исторический статус прямого и обратного и т. д.

Далее идет процесс рендеринга.

Вторая стадия

1. Во-первых, нужно построить DOM-дерево. Это преобразует полученный текст HTML в древовидную структуру в памяти. Анализатор HTML этого процесса использует конечный автомат для сегментации токенов. Это позволяет анализировать в реальном времени, не дожидаясь доставки всего текста.

2. Далее выполняется расчет стиля. Сначала суммируйте все источники стилей, в том числе те, на которые ссылается ссылка, встроенные теги стиля и т. д. Они преобразуются в данные в памяти, доступные через document.styleSheets.

И эти значения стиля также будут нормализованы, например, полужирный шрифт будет преобразован в 700, преобразование цвета будет RGB и т. д.

Наконец, определенный стиль отдельного узла вычисляется в соответствии с правилами наследования и каскадными правилами, доступ к которым можно получить, вызвав Window.getComputedStyle().

3. Следующая фаза макета. Он может вычислить геометрическое положение каждого элемента. В частности, он объединяет дерево DOM и ComputedStyle, например, он удалит узел элемента display:none.

4. Затем наступает этап обновления дерева слоев. То, что мы видим, на самом деле представляет собой многослойную 2D-страницу, поэтому браузер будет наслаивать этот сегмент в соответствии с некоторыми характеристиками.

В частности, каждый узел будет прямо или косвенно принадлежать слою. Элементы со свойствами стекового контекста находятся в отдельном слое, полосы прокрутки — в отдельном слое и так далее.

Стоит отметить, что типичное свойство CSS — will-change предоставляет разработчикам возможность явно создавать отдельные контексты стека.

5. Ниже показан этап рисования, но на этом этапе создается только очередь команд рисования.

В конце концов, он был передан потоку композиции (статус выполнения его задачи можно посмотреть в Compositor на левой панели Performance) для конкретного синтеза. Конечным продуктом рисования является изображение, браузер отправит его в задний буфер видеокарты. Тогда GPU поменяет местами передний и задний буферы, а монитор будет считывать картинку из переднего буфера. Наша страница будет отображаться перед вами!

На сегодня все. Меня зовут Закари, и я буду продолжать публиковать истории, связанные с веб-разработкой. Если вам нравятся такие истории и вы хотите поддержать меня, пожалуйста, подумайте о том, чтобы стать участником Medium. Это стоит 5 долларов в месяц и дает вам неограниченный доступ к контенту Medium. Я получу небольшую комиссию, если вы зарегистрируетесь по моей ссылке.

Ваша поддержка очень важна для меня — спасибо.