Блог
Анатолия Борисова

Как повысить свою долю в экспорте программного
обеспечения из России до 1 000 000 рублей в год?

Подарок

для каждого подписавшегося
на нашу рассылку

Что происходит, когда вы набираете google.com в адресной строке браузера и нажимаете Enter?

Перевод популярного репозитория alex/what-happens-when (42.7k ★ на GitHub). Лицензия: Creative Commons Zero.


Содержание

  1. Нажатие клавиши «g»
  2. Клавиша «Enter» нажата до упора
  3. Срабатывание прерывания (не для USB-клавиатур)
  4. Windows: отправка сообщения WM_KEYDOWN
  5. OS X: отправка NSEvent KeyDown
  6. GNU/Linux: Xorg-сервер слушает коды клавиш
  7. Разбор URL
  8. URL или поисковый запрос?
  9. Преобразование не-ASCII символов Unicode в имени хоста
  10. Проверка списка HSTS
  11. DNS-запрос
  12. Процесс ARP
  13. Открытие сокета
  14. TLS-рукопожатие
  15. Если пакет потерян
  16. Протокол HTTP
  17. Обработка запроса HTTP-сервером
  18. За кулисами браузера
  19. Браузер
  20. Парсинг HTML
  21. Интерпретация CSS
  22. Отрисовка страницы (Page Rendering)
  23. GPU-рендеринг
  24. Window Server
  25. Пост-рендеринг и действия пользователя

↑ К содержанию


1. Нажатие клавиши «g»

Следующие разделы описывают физические действия клавиатуры и прерывания операционной системы. Когда вы нажимаете клавишу «g», браузер получает событие и срабатывают функции автодополнения. В зависимости от алгоритма вашего браузера и того, находитесь ли вы в режиме приватного просмотра (инкогнито), в выпадающем списке под адресной строкой появятся различные варианты. Большинство этих алгоритмов сортируют и приоритизируют результаты на основе истории поиска, закладок, cookies и популярных запросов из интернета. По мере того как вы вводите «google.com», выполняется множество блоков кода, и предложения уточняются с каждым нажатием клавиши. Браузер может предложить «google.com» ещё до того, как вы закончите набирать.

↑ К содержанию

2. Клавиша «Enter» нажата до упора

Выберем нулевую точку отсчёта: клавиша Enter достигла нижней границы своего хода. В этот момент замыкается электрическая цепь, соответствующая клавише Enter (напрямую или ёмкостно). Это позволяет небольшому количеству тока пройти через логические цепи клавиатуры, которые сканируют состояние каждого переключателя, устраняют электрический шум (дребезг контактов) от быстрого прерывистого замыкания и преобразуют его в целочисленный код клавиши — в данном случае 13. Затем контроллер клавиатуры кодирует этот код для передачи на компьютер. Сегодня это почти повсеместно происходит по USB или Bluetooth, хотя исторически использовались подключения PS/2 и ADB.

В случае USB-клавиатуры:

  • USB-схема клавиатуры питается от 5 В, подаваемых по контакту 1 от USB-контроллера хоста компьютера.
  • Сгенерированный код клавиши сохраняется во внутренней памяти клавиатуры в регистре, называемом «endpoint».
  • USB-контроллер хоста опрашивает этот «endpoint» примерно каждые ~10 мс (минимальное значение, заявленное клавиатурой) и получает сохранённый код клавиши.
  • Значение поступает в USB SIE (Serial Interface Engine) для преобразования в один или несколько USB-пакетов, соответствующих низкоуровневому протоколу USB.
  • Эти пакеты передаются дифференциальным электрическим сигналом по контактам D+ и D- (два средних) на максимальной скорости 1.5 Мб/с, так как HID-устройство (Human Interface Device) всегда объявляется «низкоскоростным устройством» (USB 2.0).
  • Этот последовательный сигнал затем декодируется USB-контроллером хоста компьютера и интерпретируется универсальным драйвером HID-клавиатуры. Значение клавиши передаётся на уровень аппаратной абстракции операционной системы.

В случае виртуальной клавиатуры (сенсорный экран):

  • Когда пользователь прикасается пальцем к современному ёмкостному сенсорному экрану, небольшое количество тока передаётся на палец. Это замыкает цепь через электростатическое поле проводящего слоя и создаёт падение напряжения в точке касания. Контроллер экрана генерирует прерывание с координатами нажатия.
  • Мобильная ОС уведомляет активное приложение о событии нажатия в одном из его GUI-элементов (в данном случае — кнопки виртуальной клавиатуры).
  • Виртуальная клавиатура генерирует программное прерывание для отправки сообщения «нажата клавиша» обратно в ОС.
  • Это прерывание уведомляет активное приложение о событии «нажата клавиша».

↑ К содержанию

3. Срабатывание прерывания [НЕ для USB-клавиатур]

Клавиатура отправляет сигналы по линии запроса прерывания (IRQ), которая контроллером прерываний отображается в вектор прерывания (целое число). ЦП использует таблицу дескрипторов прерываний (IDT) для отображения векторов прерываний на функции-обработчики (interrupt handlers), предоставляемые ядром. Когда прерывание приходит, ЦП обращается к IDT по вектору прерывания и запускает соответствующий обработчик. Таким образом, происходит переход в режим ядра.

↑ К содержанию

4. (Windows) Отправка сообщения WM_KEYDOWN приложению

HID-транспорт передаёт событие нажатия клавиши драйверу KBDHID.sys, который преобразует HID-использование в скан-код. В данном случае скан-код — VK_RETURN (0x0D). Драйвер KBDHID.sys взаимодействует с KBDCLASS.sys (драйвер класса клавиатуры), который отвечает за безопасную обработку всего клавиатурного ввода. Затем вызывается Win32K.sys (возможно, через установленные сторонние фильтры клавиатуры). Всё это происходит в режиме ядра.

Win32K.sys определяет активное окно через API GetForegroundWindow(). Этот API возвращает дескриптор окна (window handle) адресной строки браузера. Основной «цикл сообщений» Windows вызывает SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, lParam). lParam — битовая маска с дополнительной информацией о нажатии: количество повторов (0 в данном случае), фактический скан-код, были ли нажаты дополнительные клавиши (alt, shift, ctrl) и другое состояние.

Windows SendMessage API добавляет сообщение в очередь для конкретного дескриптора окна (hWnd). Позже вызывается основная функция обработки сообщений (WindowProc), назначенная для hWnd, для обработки каждого сообщения в очереди. Активное окно является элементом управления редактирования (edit control), и его WindowProc имеет обработчик сообщений WM_KEYDOWN. Этот код проверяет третий параметр (wParam) — поскольку это VK_RETURN, он определяет, что пользователь нажал клавишу Enter.

↑ К содержанию

5. (OS X) Отправка NSEvent KeyDown приложению

Сигнал прерывания запускает событие прерывания в драйвере клавиатуры I/O Kit kext. Драйвер преобразует сигнал в код клавиши, который передаётся процессу WindowServer в OS X. В результате WindowServer отправляет событие соответствующим (активным или слушающим) приложениям через их Mach-порт, где оно помещается в очередь событий. Потоки с достаточными привилегиями могут считывать события из этой очереди, вызывая функцию mach_ipc_dispatch. Чаще всего это происходит через основной цикл событий NSApplication, в виде NSEvent типа NSEventType KeyDown.

↑ К содержанию

6. (GNU/Linux) Xorg-сервер слушает коды клавиш

Когда используется графический X server, X использует универсальный драйвер событий evdev для получения нажатия клавиши. Выполняется переназначение кодов клавиш в скан-коды с помощью карт клавиш и правил, специфичных для X server. Когда маппинг скан-кода нажатой клавиши завершён, X server отправляет символ оконному менеджеру (DWM, metacity, i3 и т.д.), который, в свою очередь, передаёт символ в активное окно. Графический API окна, получившего символ, отображает соответствующий глиф шрифта в соответствующем поле ввода.

↑ К содержанию

7. Разбор URL

Теперь браузер имеет следующую информацию, содержащуюся в URL (Uniform Resource Locator):

  • Протокол — «http»: использовать Hyper Text Transfer Protocol
  • Ресурс — «/»: получить главную (индексную) страницу

↑ К содержанию

Когда протокол или допустимое доменное имя не указаны, браузер передаёт введённый текст в поисковую систему по умолчанию. Во многих случаях к URL добавляется специальный фрагмент текста, сообщающий поисковой системе, что запрос поступил из адресной строки конкретного браузера.

↑ К содержанию

9. Преобразование не-ASCII символов Unicode в имени хоста

Браузер проверяет имя хоста на наличие символов, не входящих в набор a-z, A-Z, 0-9, - или .. Поскольку имя хоста — google.com, таких символов не будет, но если бы они были, браузер применил бы кодировку Punycode к части URL с именем хоста.

↑ К содержанию

10. Проверка списка HSTS

Браузер проверяет свой предзагруженный список HSTS (HTTP Strict Transport Security). Это список веб-сайтов, которые запросили соединение исключительно по HTTPS.

Если веб-сайт находится в списке, браузер отправляет запрос по HTTPS вместо HTTP. В противном случае первоначальный запрос отправляется по HTTP. (Обратите внимание: веб-сайт может использовать политику HSTS и без включения в список. Первый HTTP-запрос к веб-сайту от пользователя получит ответ с требованием отправлять только HTTPS-запросы. Однако этот единственный HTTP-запрос потенциально делает пользователя уязвимым для атаки на понижение протокола, поэтому список HSTS включён в современные веб-браузеры.)

↑ К содержанию

11. DNS-запрос

  • Браузер проверяет, есть ли домен в его кэше (в Chrome: chrome://net-internals/#dns).
  • Если не найден, браузер вызывает библиотечную функцию gethostbyname (зависит от ОС) для выполнения поиска.
  • gethostbyname проверяет, можно ли разрешить имя хоста с помощью локального файла hosts (расположение зависит от ОС), прежде чем пытаться разрешить имя хоста через DNS.
  • Если gethostbyname не имеет его в кэше и не может найти в файле hosts, он делает запрос к DNS-серверу, настроенному в сетевом стеке. Обычно это локальный маршрутизатор или кэширующий DNS-сервер провайдера.
  • Если DNS-сервер находится в той же подсети, сетевая библиотека следует процессу ARP (описан ниже) для DNS-сервера.
  • Если DNS-сервер находится в другой подсети, сетевая библиотека следует процессу ARP для IP-адреса шлюза по умолчанию.

↑ К содержанию

12. Процесс ARP

Для отправки широковещательного ARP-запроса (Address Resolution Protocol) сетевой библиотеке нужен целевой IP-адрес для поиска, а также MAC-адрес интерфейса, через который будет отправлен ARP-запрос.

Сначала проверяется ARP-кэш на наличие записи для целевого IP. Если запись найдена, функция возвращает результат: Целевой IP = MAC.

Если записи в ARP-кэше нет:

  • Проверяется таблица маршрутизации — находится ли целевой IP-адрес в какой-либо из подсетей. Если да, библиотека использует интерфейс, связанный с этой подсетью. Если нет — используется интерфейс с подсетью шлюза по умолчанию.
  • Определяется MAC-адрес выбранного сетевого интерфейса.
  • Сетевая библиотека отправляет ARP-запрос уровня 2 (канальный уровень модели OSI).

ARP-запрос:

Sender MAC: interface:mac:address:here
Sender IP: interface.ip.goes.here
Target MAC: FF:FF:FF:FF:FF:FF (Broadcast)
Target IP: target.ip.goes.here

В зависимости от того, какое оборудование находится между компьютером и маршрутизатором:

Прямое подключение: маршрутизатор отвечает ARP Reply.

Хаб: хаб транслирует ARP-запрос на все остальные порты. Если маршрутизатор подключён к тому же «проводу», он ответит ARP Reply.

Коммутатор (Switch): коммутатор проверяет свою локальную таблицу CAM/MAC, чтобы определить, на каком порту находится нужный MAC-адрес. Если записи нет — перенаправляет ARP-запрос на все порты. Если запись есть — отправляет только на нужный порт.

ARP-ответ:

Sender MAC: target:mac:address:here
Sender IP: target.ip.goes.here
Target MAC: interface:mac:address:here
Target IP: interface.ip.goes.here

Теперь, когда сетевая библиотека имеет IP-адрес DNS-сервера или шлюза по умолчанию, она может продолжить процесс DNS:

  • DNS-клиент устанавливает сокет на UDP-порт 53 DNS-сервера с исходным портом выше 1023.
  • Если размер ответа слишком велик, вместо UDP используется TCP.
  • Если локальный DNS-сервер / DNS-сервер провайдера не имеет записи, выполняется рекурсивный поиск вверх по цепочке DNS-серверов до SOA (Start of Authority), и если запись найдена, возвращается ответ.

↑ К содержанию

13. Открытие сокета

Получив IP-адрес сервера назначения, браузер берёт его и номер порта из URL (HTTP по умолчанию использует порт 80, HTTPS — порт 443) и вызывает системную функцию socket, запрашивая TCP-сокет (AF_INET/AF_INET6 и SOCK_STREAM).

  • Запрос передаётся на транспортный уровень, где создаётся TCP-сегмент. Порт назначения добавляется в заголовок, а исходный порт выбирается из динамического диапазона ядра (ip_local_port_range в Linux).
  • Сегмент передаётся на сетевой уровень, который добавляет IP-заголовок с IP-адресами источника и назначения.
  • Пакет поступает на канальный уровень. Добавляется заголовок кадра с MAC-адресами сетевой карты машины и шлюза (локального маршрутизатора). Если ядро не знает MAC-адрес шлюза, оно отправляет ARP-запрос.

На этом этапе пакет готов к передаче по одному из каналов:

Для большинства домашних или небольших офисных подключений пакет пройдёт от компьютера, возможно, через локальную сеть, а затем через модем (MOdulator/DEModulator), который преобразует цифровые 1 и 0 в аналоговый сигнал для передачи по телефонной, кабельной или беспроводной линии. На другом конце другой модем преобразует аналоговый сигнал обратно в цифровые данные. Более крупные организации и некоторые современные жилые подключения используют оптоволокно или прямое Ethernet-соединение.

В конечном итоге пакет достигнет маршрутизатора, управляющего локальной подсетью. Оттуда он продолжит путь к пограничным маршрутизаторам автономной системы (AS), другим AS и, наконец, к серверу назначения. Каждый маршрутизатор по пути извлекает адрес назначения из IP-заголовка и направляет пакет на следующий переход. Поле TTL (Time to Live) уменьшается на единицу на каждом маршрутизаторе. Пакет будет отброшен, если TTL достигнет нуля или если маршрутизатор не имеет места в очереди.

Эта отправка и получение происходит несколько раз в процессе установления TCP-соединения:

  • Клиент выбирает начальный порядковый номер (ISN) и отправляет пакет серверу с установленным флагом SYN.
  • Сервер получает SYN и, если согласен: выбирает собственный ISN, устанавливает SYN, копирует (ISN клиента + 1) в поле ACK и добавляет флаг ACK.
  • Клиент подтверждает соединение, отправляя пакет: увеличивает свой порядковый номер, увеличивает номер подтверждения получателя, устанавливает поле ACK.
  • Передача данных: при отправке N байт данных одной стороной её SEQ увеличивается на это число. Принимающая сторона отправляет ACK-пакет со значением ACK, равным последнему полученному порядковому номеру.
  • Закрытие соединения: закрывающая сторона отправляет FIN-пакет. Другая сторона подтверждает FIN и отправляет свой FIN. Инициатор подтверждает FIN другой стороны с помощью ACK.

↑ К содержанию

14. TLS-рукопожатие (TLS Handshake)

  • Клиентский компьютер отправляет серверу сообщение ClientHello с версией TLS, списком доступных алгоритмов шифрования и методов сжатия.
  • Сервер отвечает сообщением ServerHello с выбранной версией TLS, выбранным шифром, методом сжатия и публичным сертификатом сервера, подписанным центром сертификации (CA). Сертификат содержит открытый ключ, который клиент будет использовать для шифрования остальной части рукопожатия до согласования симметричного ключа.
  • Клиент проверяет цифровой сертификат сервера по своему списку доверенных CA. Если доверие установлено, клиент генерирует строку псевдослучайных байтов и шифрует её открытым ключом сервера. Эти случайные байты используются для определения симметричного ключа.
  • Сервер расшифровывает случайные байты своим закрытым ключом и использует их для генерации собственной копии симметричного мастер-ключа.
  • Клиент отправляет серверу сообщение Finished, зашифровывая хеш передачи до этого момента симметричным ключом.
  • Сервер генерирует собственный хеш, расшифровывает хеш клиента и проверяет совпадение. Если совпадает, отправляет собственное сообщение Finished, также зашифрованное симметричным ключом.
  • С этого момента TLS-сессия передаёт данные приложения (HTTP), зашифрованные согласованным симметричным ключом.

↑ К содержанию

15. Если пакет потерян

Иногда из-за перегрузки сети или нестабильных аппаратных соединений TLS-пакеты теряются, не достигнув пункта назначения. Отправитель должен решить, как реагировать. Алгоритм для этого называется управление перегрузкой TCP. Он зависит от отправителя; наиболее распространённые алгоритмы — cubic в новых ОС и New Reno в большинстве остальных.

  • Клиент выбирает окно перегрузки (congestion window) на основе максимального размера сегмента (MSS) соединения.
  • Для каждого подтверждённого пакета окно удваивается, пока не достигнет «порога медленного старта» (slow-start threshold). В некоторых реализациях этот порог адаптивный.
  • После достижения порога окно увеличивается аддитивно для каждого подтверждённого пакета. При потере пакета окно уменьшается экспоненциально до подтверждения следующего пакета.

↑ К содержанию

16. Протокол HTTP

Если браузер написан Google, вместо отправки HTTP-запроса для получения страницы он попытается договориться с сервером об «апгрейде» с HTTP на протокол SPDY.

Если клиент использует протокол HTTP и не поддерживает SPDY, он отправляет серверу запрос вида:

GET / HTTP/1.1
Host: google.com
Connection: close
[другие заголовки]

где [другие заголовки] — серия пар «ключ: значение», разделённых двоеточием, в соответствии со спецификацией HTTP и разделённых переводами строк.

HTTP/1.1 определяет опцию соединения «close» для сигнала отправителя о том, что соединение будет закрыто после завершения ответа. Приложения HTTP/1.1, не поддерживающие постоянные соединения, должны включать опцию «close» в каждое сообщение.

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

Сервер отвечает кодом состояния, обозначающим статус запроса:

200 OK
[заголовки ответа]

За ним следует пустая строка, а затем — тело ответа с HTML-содержимым www.google.com. Сервер может затем закрыть соединение или, если клиент запросил, оставить его открытым для дальнейших запросов.

Если HTTP-заголовки браузера содержали достаточно информации для определения того, что кэшированная версия файла не изменилась с момента последнего получения (например, заголовок ETag), сервер может ответить:

304 Not Modified
[заголовки ответа]

без тела ответа, и браузер получит HTML из своего кэша.

После разбора HTML браузер (и сервер) повторяют этот процесс для каждого ресурса (изображения, CSS, favicon.ico и т.д.), на который ссылается HTML-страница.

↑ К содержанию

17. Обработка запроса HTTP-сервером

HTTPD (HTTP Daemon) — это серверное ПО, обрабатывающее запросы и ответы на стороне сервера. Наиболее распространённые HTTPD-серверы: Apache и nginx для Linux, IIS для Windows.

  • HTTPD получает запрос.
  • Сервер разбирает запрос на параметры:
    • Метод HTTP-запроса (GET, HEAD, POST, PUT, PATCH, DELETE, CONNECT, OPTIONS или TRACE). В случае URL, введённого в адресную строку, это будет GET.
    • Домен — в данном случае google.com.
    • Запрошенный путь/страница — в данном случае / (так как конкретный путь не был запрошен, / является путём по умолчанию).
  • Сервер проверяет, что на сервере настроен виртуальный хост, соответствующий google.com.
  • Сервер проверяет, что google.com может принимать GET-запросы.
  • Сервер проверяет, что клиенту разрешено использовать этот метод (по IP, аутентификации и т.д.).
  • Если на сервере установлен модуль перезаписи URL (например, mod_rewrite для Apache или URL Rewrite для IIS), он пытается сопоставить запрос с одним из настроенных правил. Если найдено совпадение, сервер перезаписывает запрос.
  • Сервер извлекает контент, соответствующий запросу — в нашем случае это будет индексный файл, так как «/» — главный файл.
  • Сервер парсит файл в соответствии с обработчиком. Если Google работает на PHP, сервер использует PHP для интерпретации индексного файла и передаёт результат клиенту.

↑ К содержанию

18. За кулисами браузера

Как только сервер предоставляет ресурсы (HTML, CSS, JS, изображения и т.д.), браузер выполняет следующий процесс:

  • Парсинг — HTML, CSS, JS
  • Рендеринг — построение DOM-дерева → Render Tree → компоновка Render Tree → отрисовка Render Tree

↑ К содержанию

19. Браузер

Функция браузера — представлять выбранный вами веб-ресурс, запрашивая его с сервера и отображая в окне браузера. Ресурсом обычно является HTML-документ, но это также может быть PDF, изображение или другой тип контента. Расположение ресурса задаётся пользователем с помощью URI (Uniform Resource Identifier).

Способ интерпретации и отображения HTML-файлов определяется спецификациями HTML и CSS, которые поддерживаются организацией W3C (World Wide Web Consortium) — организацией по стандартизации для веба.

Высокоуровневая структура браузера:

  • Пользовательский интерфейс: адресная строка, кнопки вперёд/назад, меню закладок и т.д. — всё, кроме области отображения запрошенной страницы.
  • Движок браузера (Browser engine): координирует действия между интерфейсом и движком рендеринга.
  • Движок рендеринга (Rendering engine): отвечает за отображение запрошенного контента. Парсит HTML и CSS и отображает результат на экране.
  • Сетевой модуль (Networking): обрабатывает сетевые вызовы, такие как HTTP-запросы, используя различные реализации для разных платформ за платформонезависимым интерфейсом.
  • UI-бэкенд: используется для отрисовки базовых виджетов (комбо-боксы, окна). Предоставляет универсальный интерфейс, использующий методы пользовательского интерфейса ОС.
  • JavaScript-движок: используется для парсинга и выполнения JavaScript-кода.
  • Хранилище данных (Data storage): слой постоянного хранения. Браузер может сохранять различные данные локально: cookies, localStorage, IndexedDB, WebSQL и FileSystem.

↑ К содержанию

20. Парсинг HTML

Движок рендеринга начинает получать содержимое запрошенного документа от сетевого уровня, обычно порциями по 8 КБ.

Основная задача HTML-парсера — преобразовать HTML-разметку в дерево разбора (parse tree). Выходное дерево — это дерево DOM-элементов и узлов атрибутов. DOM (Document Object Model) — это объектное представление HTML-документа и интерфейс HTML-элементов с внешним миром, например, с JavaScript. Корень дерева — объект «Document». До любых манипуляций через скрипты DOM почти один-к-одному соответствует разметке.

Алгоритм парсинга:

HTML нельзя разобрать обычными нисходящими или восходящими парсерами. Причины:

  • Прощающая природа языка.
  • Браузеры традиционно толерантны к ошибкам и поддерживают известные случаи невалидного HTML.
  • Процесс парсинга реентрантен: для других языков исходный код не меняется во время парсинга, но в HTML динамический код (например, элементы script с вызовами document.write()) может добавлять дополнительные токены, фактически изменяя входные данные.

Не имея возможности использовать обычные техники парсинга, браузер применяет специальный парсер для HTML. Алгоритм подробно описан в спецификации HTML5 и состоит из двух этапов: токенизация и построение дерева.

Действия после завершения парсинга:

Браузер начинает загрузку внешних ресурсов, связанных со страницей (CSS, изображения, JavaScript-файлы и т.д.). На этом этапе документ помечается как интерактивный, и начинается парсинг скриптов в «отложенном» режиме (deferred). Состояние документа устанавливается в «complete», и генерируется событие «load».

Обратите внимание: на HTML-странице никогда не возникает ошибки «Invalid Syntax». Браузеры исправляют любой невалидный контент и продолжают работу.

↑ К содержанию

21. Интерпретация CSS

  • CSS-файлы, содержимое тегов <style> и значения атрибутов style разбираются с использованием лексической и синтаксической грамматики CSS.
  • Каждый CSS-файл парсится в объект StyleSheet, содержащий CSS-правила с селекторами и объектами, соответствующими CSS-грамматике.
  • CSS-парсер может быть нисходящим или восходящим, в зависимости от используемого генератора парсеров.

↑ К содержанию

22. Отрисовка страницы (Page Rendering)

  • Создаётся «дерево фреймов» или «дерево рендеринга» (Render Tree) путём обхода узлов DOM и вычисления CSS-стилей для каждого узла.
  • Вычисляется предпочтительная ширина каждого узла «снизу вверх» (суммируются предпочтительные ширины дочерних узлов и горизонтальные отступы, границы, поля).
  • Вычисляется фактическая ширина каждого узла «сверху вниз» — доступная ширина распределяется между дочерними узлами.
  • Вычисляется высота каждого узла «снизу вверх» путём применения переноса текста и суммирования высот дочерних узлов, отступов, границ и полей.
  • Вычисляются координаты каждого узла.
  • Более сложные шаги выполняются для элементов с float, абсолютным или относительным позиционированием и другими сложными свойствами.
  • Создаются слои, описывающие, какие части страницы можно анимировать как группу без повторной растеризации. Каждому фрейму/render-объекту назначается слой.
  • Для каждого слоя выделяются текстуры.
  • Фреймы/render-объекты каждого слоя обходятся, и выполняются команды отрисовки. Это может быть растеризация на CPU или отрисовка на GPU с использованием D2D/SkiaGL.
  • Все вышеперечисленные шаги могут повторно использовать значения, вычисленные при предыдущем рендеринге страницы, чтобы инкрементальные изменения требовали меньше работы.
  • Слои страницы отправляются в процесс композитинга, где они комбинируются со слоями другого видимого контента (хром браузера, iframe, панели расширений).
  • Вычисляются финальные позиции слоёв, и команды композитинга отправляются через Direct3D/OpenGL. Буферы команд GPU сбрасываются на GPU для асинхронного рендеринга, и кадр отправляется в Window Server.

↑ К содержанию

23. GPU-рендеринг

В процессе рендеринга графические вычислительные слои могут использовать как обычный CPU, так и графический процессор GPU. При использовании GPU для графических вычислений программные графические слои разделяют задачу на множество частей, чтобы задействовать массивный параллелизм GPU для вычислений с плавающей запятой, необходимых для процесса рендеринга.

↑ К содержанию

24. Window Server

(Раздел присутствует в оригинале как заглушка без содержания.)

↑ К содержанию

25. Пост-рендеринг и действия пользователя

После завершения рендеринга браузер выполняет JavaScript-код как результат некоторого механизма таймеров (например, анимация Google Doodle) или взаимодействия пользователя (ввод запроса в поисковое поле и получение подсказок). Плагины вроде Flash или Java также могут выполняться, хотя на главной странице Google в данный момент этого не происходит. Скрипты могут инициировать дополнительные сетевые запросы, а также модифицировать страницу или её макет, вызывая новый цикл рендеринга и отрисовки.

↑ К содержанию


Оригинал: github.com/alex/what-happens-when · Лицензия: CC0 · Перевод на русский язык.

Обложка от pvproductions на Freepick

Комментариев еще нет.

Оставить комментарий