Устройство современного веб-браузера Chrome (часть 1/4) +13


Оригинальное название публикации: "Inside look at modern web browser".


В этой серии, состоящей из 4 частей, мы рассмотрим внутренности браузера Chrome от архитектуры высокого уровня до особенностей пайплайна рендеринга. Если вы когда-нибудь задумывались над тем, как браузер превращает ваш код в функциональный сайт, или не знаете, почему для повышения производительности предлагается та или иная методика, то эта серия статей для вас.



Об особенностях перевода
  • в ходе перевода, я старался вычленять из статьи ПОНЯТИЯ, т.е. текстовые единицы которые несут специальный (технический) смысл. В переводе эти понятия выделены по особенному — во первых понятия предваряются символом звёздочки, во-вторых в них вместо пробела используется тире. Например: *браузер-процесс, *сайто-изоляция. При переводе понятий, приоритет отдавался не красоте перевода, а желанию выделить, акцентировать, то что мы имеем дело с ПОНЯТИЕМ, а не с фигурой речи.
  • также, некоторые слова переведены неверно с точки зрения русского языка, в жаргонном стиле, например пайплайн, продакшен. У "технарей" такой перевод не вызовет затруднений, у остальных читателей прошу прощения.

Часть 1 (текущая)
Часть 2
Часть 3
Часть 4


CPU, GPU, память, и мультипроцессорная архитектура


В первой части этой серии мы рассмотрим основную компьютерную терминологию и многопроцессорную архитектуру Chrome.


Примечание: Если вы знакомы с идеей CPU/GPU и процессами/потоками, вы можете сразу перейти к главе "Архитектура браузера".


Серцем компьютера являются CPU и GPU


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


= CPU


Во-первых, это центральный процессор или CPU. Центральный процессор можно считать мозгом вашего компьютера. Ядро CPU, изображенное здесь в виде офисного работника, может выполнять множество различных задач по мере их поступления. Оно может справиться со всем, начиная от математики и заканчивая искусством, при этом зная, как ответить на вызов клиента. Раньше большинство процессоров представляли собой один чип. Ядро похоже на еще один процессор, живущий в этом чипе. В современном аппаратном обеспечении вы часто получаете более одного ядра, дающего больше вычислительной мощности вашим телефонам и ноутбукам.



Рис.1: 4 ядра CPU похожи на офисных работников сидящих каждый за своим столом и выполняющих задачи по мере их поступления


= GPU


Графический процессор — или GPU — это еще одна часть компьютера. В отличие от CPU, GPU хорошо справляется с простыми задачами, но на нескольких ядрах одновременно. Как следует из названия, он изначально разрабатывался для работы с графикой. Именно поэтому в контексте графики "использование GPU" или "GPU-поддержки" ассоциируется с быстрым рендерингом и плавным взаимодействием. В последние годы, благодаря ускорению вычислений на GPU, все больше и больше вычислений становятся возможными только на GPU.



Рис.2: Множество GPU ядер с гаечным ключём олицетворяют что они могут выполнять ограниченные задачи


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



Рис.3: Три уровня компьютерной архитектуры. Оборудование внизу, Операционная система в середине, и Приложение на верху


Выполнение программы в Процессе и Потоке


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


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



Рис.4: Процесс как прямоугольник, потоки как абстрактная рыба плавающая внутри процесса


image


Рис.5: Диаграмма показывающая использование памяти и хранения данных приложения


Процесс может попросить операционную систему развернуть другой процесс для выполнения различных задач. Когда это происходит, для нового процесса выделяется другая часть памяти. Если двум процессам необходимо общаться, они могут сделать это с помощью межпроцессного взаимодействия (IPC). Многие приложения разработаны таким образом, что если worker процесс не реагирует, его можно перезапустить, не останавливая другие процессы, выполняющие разные части приложения.


image


Рис.6: Диаграмма разных процессов взаимодействующих через IPC


Архитектура браузера


Так как же веб-браузер создан используя процессы и потоки? Ок, это может быть один процесс с большим количеством различных потоков или много различных процессов с несколькими потоками, взаимодействующими через IPC.



Рис.7: Различные архитектуры браузеров в виде схемы процессов/потоков


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


Ради этого цикла статей в блоге мы будем использовать последнюю архитектуру Chrome, описанную на схеме ниже.


Вверху находится *браузер-процесс (Browser Process), координирующийся с другими процессами, которые заботятся о различных частях приложения. Для рендеринга создается несколько процессов (*рендер-процессы), которые назначаются каждой вкладке. До недавнего времени Chrome давал каждой вкладке свой процесс, когда это было возможно, теперь он пытается дать собственный процесс отдельному сайту, включая iframes (см. раздел "Изоляция сайта" ниже).



Рисунок 8: Схема многопроцессорной архитектуры Chrome. У *рендер-процесса показаны несколько слоев, которые обозначают несколько *рендер-процессов выполняющихся для каждой вкладки


Какой процесс что контролирует?


Ниже описан каждый процесс Chrome и что каждый из них контролирует:


Browser (*браузер-процесс)


Управляет "chrome" частью приложения, включая адресную строку, закладки, кнопки "назад" и "вперед". Также управляет невидимыми, привилегированными частями веб-браузера, такими как сетевые запросы и доступ к файлам.


Renderer (*рендер-процесс)


Управляет всем, что находится внутри вкладки, на которой отображается веб-сайт.


Plugin (*плагин-процесс)


Управляет любыми плагинами, используемыми сайтом, например, flash.


GPU (*GPU-процесс)


Обрабатывает задачи GPU изолированно от других процессов. Он выделен в отдельный процесс, потому что GPU обрабатывает запросы от нескольких приложений и рисует их на одной и той же поверхности.



Рисунок 9: Различные процессы, отвечающие за различные части пользовательского интерфейса браузера


Есть еще процессы, например процесс Extension и утилитные процессы. Если вы хотите посмотреть, сколько процессов запущено в Chrome, щелкните по значку меню параметров (три вертикальные точки) в правом верхнем углу, выберите "Дополнительные инструменты", затем выберите "Диспетчер задач". Откроется окно со списком процессов, которые запущены в данный момент, и будет показано сколько процессора/памяти они используют.


Выгоды от мультипроцессорной архитектуры в Chrome


Ранее я упоминала, что в Chrome используется несколько *рендер-процессов. В самом простом случае можно представить, что каждая вкладка имеет свой собственный *рендер-процесс. Допустим, у вас открыто 3 вкладки, и каждая из них запускается с независимым *рендер-процессом. Если одна из вкладок становится неотзывчивой, то можно закрыть её и двигаться дальше, сохранив при этом другие вкладки. Если все вкладки выполняются в одном процессе, то когда одна из них становится неотзывчивой, становятся неотзывчивыми и все остальные. Это не радует.


image


Рис.10: Схема показывающая несколько процессов работающих отдельно для каждой вкладки


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


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


Экономим память — сервисность в Chrome


Такой же подход применяется и к *браузер-процессу. Chrome претерпел архитектурные изменения для запуска каждой части браузерной программы как сервиса, позволяющие легко разбиваться на разные процессы или объединять их в один.


Общая идея заключается в том, что когда Chrome работает на мощном аппаратном обеспечении, он может разделить каждый сервис на разные процессы, давая бОльшую стабильность, но если он работает на устройстве, с ограниченными ресурсами, то Chrome консолидирует сервисы в один процесс, экономя память. Аналогичный подход к консолидации процессов для меньшего использования памяти используется так же в Android.



image


Рисунок 11: Схема сервисности Chrome, на которой различные сервисы переносятся в несколько процессов и наоборот в один *бразуер-процесс


Процессы рендеринга и iframes — *Сайто-изоляция


*Сайто-изоляция — это недавно введенная в Chrome функция, которая запускает отдельный *рендер-процесс для каждого кросс-сайтового iframe. Мы говорим об одном *рендер-процессе для каждой модели вкладки, который позволяет запускать кросс-сайтовые iframes в одном *рендер-процессе с разделением пространства памяти между разными сайтами. Запуск a.com и b.com в одном и том же *рендер-процессе кажется нормальным. Same Origin Policy является основной моделью безопасности в Интернете; она гарантирует, что один сайт не может получить доступ к данным с других сайтов без согласия. Обход этой политики является основной целью при атаках на безопасность. Изоляция процесса является наиболее эффективным способом разделения сайтов. Благодаря уязвимостям Meltdown and Spectre стало еще более очевидным, что нам нужно разделять сайты используя процессы. С включенной *сайто-изоляцией на ПК по умолчанию, начиная с Chrome 67, каждый межсайтовый iframe во вкладке получает отдельный *рендер-процесс.



Рисунок 12: Схема *сайто-изоляции; несколько *рендер-процессов используются для iframes внутри сайта


Создание *сайто-изоляции стало результатом многолетней инженерной работы. Изоляция сайта не так проста, как использование разных *рендер-процессов; она принципиально меняет способ общения iframes друг с другом. Открытие devtools на странице с iframes, запущенными на разных процессах, означает, что devtools должен был реализовать фоновую работу, чтобы это выглядело незаметно. Даже запуск простого Ctrl+F для поиска слова на странице означает поиск по различным *рендер-процессам. Теперь вы можете понять причину, по которой разработчики браузеров говорят о реализации *сайто-изоляции как о важной вехе!


Краткие итоги


В этом посте мы сделали высокоуровневый взгляд на архитектуру браузера и преимущества многопроцессорной архитектуры. Мы также рассказали о сервисности и *сайт-изоляции в Chrome, которая тесно связана с многопроцессорной архитектурой. В следующем посте мы начнем размышлять о том, как взаимодействуют процессы и потоки, чтобы отобразить веб-сайт.


Часть 1 (текущая)
Часть 2
Часть 3
Часть 4




К сожалению, не доступен сервер mySQL