Нужна ли многопоточность процессора для браузера
= Шаг 4. Реализация перехода
Теперь, когда данные и *рендер-процесс готовы, выполняется IPC запрос из *браузер-процесса в *рендер-процесс для реализации перехода. Также передается стрим данных, для того чтобы *рендер-процесс мог продолжать получать HTML-данные. Как только *браузер-процесс получает подтверждение того, что в *рендер-процессе всё выполнено, навигация завершается и начинается фаза загрузки документа.
Рисунок 6: IPC между *браузер-процессом и *рендер-процессом, запрос на рендеринг страницы
Особенности старых компьютеров
Три фактора, ограничивающие производительность компьютера — это процессор, оперативная память и диск. Архитектура CPU меняется от поколения к поколению, и если между соседними поколениями не такая значительная разница, то есть мы берем разницу в несколько поколений, разница может быть значительна. И дело не столько в частоте процессора или системной шины, сколько в количестве и архитектуре ядер, поддержке команд различных поколений и размере кэшей и точности в них попадания.
(3) Взаимодействие между выполнением js-кода (Event Loop) и другими потоками.
Механизм JavaScript не работает независимо, он работает в среде хоста, которой для большинства разработчиков обычно является веб-браузер. Предоставляет механизм для обработки выполнения нескольких блоков в программе (блок здесь можно понимать как несколько функций возврата) и вызывает механизм JavaScript при выполнении каждого блока. Этот механизм называется циклом событий. Другими словами, сам движок JavaScript не имеет понятия времени, это среда, которая выполняет произвольные фрагменты кода JavaScript по запросу. Планирование «событий» (выполнение кода JavaScript ) всегда выполняется средой, которая его содержит. Это планирование планируется потоком, инициируемым событием.
Например, если ваша программа JavaScript выполняет запрос Ajax для получения некоторых данных с сервера, вы устанавливаете код ответа в функции (обычно называемой функцией обратного вызова), а затем механизм JavaScript уведомляет среду хоста (поток запуска события ): «Эй, теперь я хочу приостановить выполнение. После того, как вы завершите сетевой запрос и получите данные, вызовите эту функцию». Затем браузер будет настроен на прослушивание ответа из сети. После получения данных, которые будут переданы вам, Функция обратного вызова будет вставлена в цикл событий для достижения запланированного выполнения этого обратного вызова.
Доступ к содержимому конкретного цикла событийОсновные понятия асинхронного JavaScript
На следующем рисунке показан запрос страницы и взаимодействие между вышеуказанными процессами / потоками во время выполнения js.
Фактически, я уже читал содержание Promise раньше, вы можете проверить конкретный контентстатьяТеперь я просто показываю обещание на основе содержимого очереди задач в виде кода. Думаю, вы можете угадать результат вывода здесь:
promise run
setTimeout run
Причина здесь не так велика, потому что сначала движок js должен сначала выполнить код основного потока js (он будет выполнен первым, потому что загрузка js будет выполняться сверху вниз, и движок js успеет выйти из цикла событий. Выньте блок кода в очереди для выполнения.) Что касается setTimeout, хотя интервал времени равен 0 мс, фактическое время выполнения составляет 4 мс. И функция обратного вызова помещается в очередь цикла событий. А как насчет обещания? Например, то, что мы сейчас выполняем, - это основной поток js. После завершения выполнения механизм js не сразу перейдет в очередь цикла событий, чтобы получить блок кода для выполнения, но скажет, что у текущего основного потока есть одна вещь, которая не была завершена, то есть обещание.статьяОб этом тоже говорили в Китае. Гранулярность двух событий разная, и promsie представляет собой очередь задач над очередью цикла событий.
Для современного браузера многопроцессность — это хороший тон. Все браузеры обладают вкладками, а каждая из вкладок в многопоточном режиме является отдельным изолированным процессом. Достоинства такого подхода — не только в дополнительных мерах безопасности и исключении ряда атак. В отдельные процессы можно уводить вкладки, дополнения и расширения, к примеру, блокировщик рекламы. Если один из процессов завершится с ошибкой, работу можно продолжить без перезапуска всего браузера. Исключаются разнообразные утечки памяти, растёт производительность за счёт распараллеливания задач нескольким ядрам процессора. Если одна из вкладок потребляет много ресурсов, интерфейс не повиснет, он сохранит отзывчивость.
Многопроцессностью обладают почти все популярные браузеры: Google Chrome, Internet Explorer, Microsoft Edge, Apple Safari. Mozilla Firefox догоняет их. Electrolysis или e10s — это технология многопоточного режима в Firefox. В первых версиях процессов два: один для браузерных вкладок, второй для интерфейса. В следующих версиях процессов на контент будет несколько.
Многопроцессность можно включить самостоятельного. Чтобы убедиться, какая версия попалась, достаточно набрать в адресной строке about:support и поискать строчку Multiprocess Windows.
Не все расширения совместимы с Electrolysis. Можно посмотреть списки самых популярных дополнений на сайте Are We e10s Yet, где указан их статус совместимости в режиме многопоточного Firefox. Можно сразу включить Electrolysis и выключить его позже, если важные дополнения ломаются.
Нужный параметр в about:config (ввести в адресную строку и нажать «Ввод») — browser.tabs.remote.autostart . Значение параметра нужно установить на true двойным щелчком.
После перезапуска браузера Electrolysis может заработать. В некоторых случаях его включению будет мешать какое-то дополнение.
Чтобы обойти это ограничение, создайте в about:config новую булеву постоянную browser.tabs.remote.force-enable и присвойте ей значение true .
Теперь Electrolysis заработает в принудительном режиме многопроцессности. Обратите внимание, что подобное может отразиться на производительности некоторых дополнений. В about:support напротив Multiprocess Windows появится 1/1 (Enabled by user).
Electrolysis можно включить или отключить через about:config . А вот способа отключить обязательность подписи устанавливаемого расширения больше нет. Опция исчезла, как и было задумано.
Год назад появился первый план ввода обязательных подписей. Изначально предполагалось, что 40-я версия начнёт предупреждать об отсутствии подписи, в 41-й обязательность будет отключаемой, а с 42-й возможность установить расширения без подписи пропадёт. В скорректированной версии сроки неотключаемости сдвинули до 44-й версии. Позднее сроки сдвигались до 46-й версии.
В Firefox 49 исчезла поддержка Android 2.3 (Gingerbread), версий OS X 10.6 (Snow Leopard), 10.7 (Lion) и 10.8 (Mountain Lion). Эти операционные системы вышли 4—6 лет назад.
Улучшения безопасности при скачивании файлов содержат расширенную защиту. Теперь при попытке скачивания тех программ, которые производят непредвиденные изменения на компьютере, Firefox выдаст предупреждение. Принципы фильтрации объяснены в гугловской Unwanted Software Policy. Бразуер научился предупреждать, что загрузка необычна. К примеру, при скачивании VLC из стороннего, неофициального источника высока вероятность натолкнуться на зловред, который ещё не фильтруется Google Safe Browsing. В этом случае браузер выдаст предупреждение, что файл скачан из необычного источника.
Слева: предупреждение о потенциально нежелательной загрузке. Справа: предупреждение о скачивании зловредного файла.
API WebExtensions считается стабильным. Для пользователя это означает, что в Firefox можно устанавливать расширения Chrome. Сделать это можно с помощью расширения Chrome Store Foxified. Для работы может потребоваться подписывать дополнения на AMO, то есть будет нужен аккаунт на сайте.
Ряд косметических улучшений включает увеличенную строку поиска. Поисковых подсказок больше, они шире. Повышена читаемость. Если фавиконки кэшированы, они будут показываться.
Изменён вид about:addons , упрощёны рекомендации дополнений. Теперь их можно установить в один клик.
Firefox Hello — это инструмент для сотрудничества и общения в формате аудио- и видеочата, созданный на технологии WebRTC. Сервис встроен в Firefox с 34-й версии. В 49-й версии Hello может исчезнуть. На баг-трекере обсуждается удаление Hello из браузера уже в следующей версии. Причина удаления — смена приоритетов разработки. В ночной сборке Nightly 51 и ранней версии Aurora 50 сервис Hello уже исчез. На момент написания поста Beta 49 пока не опубликована.
Ранее из Firefox удалили темы оформления и группы вкладок из-за малоиспользуемости. Поддержка малопопулярных функций замедляла выпуск новых версий. Возможно, Hello хотят «убить» по той же причине.
Firefox продолжит избавляться от поддержки старых систем. В 49-й версии набор инструкций центрального процессора SSE2 будет обязательным для работы Firefox под Windows. Речь идёт об отказе от процессоров до эпохи Pentium 4 и Athlon 64.
Фотография самки малой панды Кинта в зоопарке Ногеяма, CC-BY 2.0.
Ни для кого не секрет, что старые компьютеры в состоянии эффективно работать только с Windows 7, но не более новыми ОС. В то же время они достаточно быстро работали с различными браузерами еще 3-4 года назад, но сильно тормозят с современными версиями тех же браузеров. Почему так происходит? Ответ в этой статье.
Особенности современных браузеров
По мере увеличения производительности компьютеров, браузеры стали делать все более требовательными к ресурсам системы, внедряя все новых функционал. Они максимально используют возможности новых CPU. Теперь, каждая закладка браузера — это отдельных процесс в памяти компьютера, и между ними процессор вынужден часто переключаться. Это хорошо с точки зрения того, что одна закладка при зависании не приводит к зависанию других, но более расточительно с точки зрения ресурсов. Кроме того, каждый плагин браузера также потребляет ресурсы памяти и процессора.
Например, 25 открытых закладок в браузере Google Chrome потребуют 1.5-1.8 Гбайт оперативной памяти и 5-10% процессорного времени процессоров последних поколений в простое, 20-50% процессорного времени более старых поколений процессоров и до 100% при нагрузке. Internet Explorer при такой загрузке просто зависает, так как в его архитектуре каждая закладка не является отдельным процессом.
Важная особенность в том, что если на одной из открытых закладок есть открытое видео или flash объекты сайта, то такая закладка будет потреблять больше ресурсов и может даже подвесить браузер целиком, потому что процессор будет испытывать трудности при переключении между процессами.
Именно поэтому при запуске браузера на старых компьютерах с сохраненными вкладками, запуск происходит по 10-30 секунд.
Разница и взаимосвязь между процессами и потоками
Процесс - это наименьшая единица операционной системы для распределения ресурсов, а поток - наименьшая единица выполнения программы.
Процесс состоит из одного или нескольких потоков, а потоки - это разные маршруты выполнения кода в процессе;
Процессы независимы друг от друга, но каждый поток в одном процессе разделяет пространство памяти программы (включая сегменты кода, наборы данных, кучи и т. д.) и некоторые ресурсы уровня процесса (например, открытие Файлы и сигналы).
Планирование и переключение: переключение контекста потока происходит намного быстрее, чем переключение контекста процесса.
Поток движка JS
Также известное как ядро JS, отвечающее за обработку программ сценариев Javascript. (Например, двигатель V8)
Поток механизма JS отвечает за синтаксический анализ скрипта Javascript и запуск кода.
Механизм JS ждал поступления задач в очередь задач, а затем обрабатывал их. Только один поток JS запускает программу JS в любой момент на странице вкладки (процесс рендеринга)
Также обратите внимание, что поток визуализации графического интерфейса пользователя и поток механизма JS являются взаимоисключающими, поэтому, если время выполнения JS слишком велико, это приведет к несогласованности отрисовки страницы и блокировке отрисовки страницы.
Многопроцессорность и многопоточность
Многопроцессорность: многопроцессорность означает, что два или более процессов могут работать в одной и той же компьютерной системе одновременно. Преимущества многопроцессорности очевидны: например, пока вы можете слушать песню, открывать редактор и вводить код, не будет никакого вмешательства между процессами редактора и программой для прослушивания музыки.
Многопоточность означает, что программа содержит несколько потоков выполнения, то есть программа может запускать несколько разных потоков для одновременного выполнения разных задач, что означает, что одна программа может создавать несколько Параллельно выполняющиеся потоки выполняют свои задачи.
(1) Почему JavaScript однопоточный?
Прежде всего, чтобы прояснить концепцию, поток движка JS живет в процессе рендеринга (процесс рендеринга браузера). Фактически, из предыдущего процесса, введения между потоками уже было понятно, что ресурсы разделяются между потоками и влияют друг на друга. Если предположить, что в работе javascript есть два потока, которые работают с одним и тем же ресурсом друг с другом, это вызовет проблемы с синхронизацией. Кто является стандартом для модификации?
Таким образом, JavaScript является однопоточным, что стало основной функцией языка и не изменится в будущем.
Как увеличить производительность старых компьютеров
Здесь имеется два направления, в которых необходимо двигаться: увеличение производительности самого компьютера и настройка браузера.
Чтобы увеличить производительность вашего компьютера без замены материнской платы сделайте следующее:
- Установите CPU c максимальным числом ядер и потоков для вашего сокета платы, а также с максимальным кэшем
- Установите не менее 2 Гбайт оперативной памяти для комфортной работы
- Установите модули памяти в двухканальном симметрично режиме (одинаковые по частоте и слоты разных каналов)
- Установите модули памяти максимальной частоты, которая позволяет ваша шина памяти
- Убедитесь, что на жестком диске не менее 5 Гбайт свободного места, чем больше — тем лучше.
- Удалите временные файлы с диска (они хранятся в разных папках — используйте CCleaner) и после выполните дефрагментацию диска.
- Если есть возможность — замените HDD на SDD — очень выиграете во времени запуска браузеров.
С точки зрения самих браузеров можно сделать следующее:
- Почистите кэш браузеров (Ctrl+Shift+Del) и настройте браузер чистить кэш регулярно
- Не оставляйте открытые закладки, закрывая браузер. Настройте браузер на запуск с чистой страницы. Любимые закладки добавьте в избранные, они будут у вас в быстром доступе.
- Удалите все расширения браузера, которая вам не нужны, а та, что не используете сейчас — отключите.
- Удалите вспомогательные поисковые панели браузера, в том числе от Яндекс.
= Шаг 1. Обработка ввода
Рисунок 1-bis: *UI-поток спрашивает, является ли входной запрос поисковым или URL-адресом
Кэш и память
Любая программа при запуске занимает какое-то пространство в оперативной памяти, а при исполнении её кода, процессор часть данных берет из оперативной памяти, а части располагает у себя в кэше для более быстрого доступа. Упрощенно говоря, туда попадают части кода (инструкции процессора), которые чаще всего используются программой. Более сложен алгоритм размещения данных в кэше. Если процессор нашел необходимые данные и инструкции в кэше, то говорят о «попадании в кэш». Это очень хорошо для производительности, ведь доступ к кэшу CPU в десятки раз быстрее, чем к оперативной памяти. Собственно, алгоритмы работы с кэшем в разных поколениях процессоров постоянно совершенствуются, потому может быть значительная разница в производительности (скажем, до 50% между 4 и 8 поколениями Intel Core при работе браузера).
Увеличение объема самого кэша позволило компилировать код программ таким образом, чтобы больше данных попадало в кэш.
Кроме того, очень важным событием в истории архитектуры процессоров стал перенос контроллера памяти с материнской плате в процессор. Это позволило значительно поднять частоту шины памяти и увеличить скорость обмена процессора с ней, ведь ранее то было узким горлышком системы.
Поток триггера события
Принадлежит браузеру, а не движку JS, используется для управления циклом событий (понятно, что сам движок JS слишком занят и требует, чтобы браузер открыл поток, чтобы помочь)
Когда механизм JS выполняет блоки кода, такие как setTimeOut (также из других потоков ядра браузера, таких как щелчки мыши, асинхронные запросы AJAX и т. д.), соответствующая задача будет добавлена в поток событий.
Когда соответствующее событие соответствует условию триггера и запускается, поток добавит событие в конец очереди для обработки, ожидая обработки JS-движком.
Обратите внимание, что из-за однопоточной связи JS события в этих ожидающих очередях должны быть поставлены в очередь для обработки механизмом JS (выполняются только тогда, когда механизм JS простаивает).
(2) Процесс и поток браузера
Сначала откройте браузер, затем откройте Shift + Esc, чтобы открыть диспетчер задач Chrome.
В настоящее время есть только три процесса:
Браузерный процесс (Браузерный процесс): Есть только один основной процесс (отвечающий за координацию и основной контроль) браузера. Роль
Отвечает за отображение интерфейса браузера и взаимодействие с пользователями. Например, вперед, назад и т. Д.
Отвечает за управление каждой страницей, создание и уничтожение других процессов.
Нарисуйте растровое изображение в памяти, полученное процессом Renderer, в пользовательский интерфейс.
Управление сетевыми ресурсами, загрузка и т. д.
Процесс GPU: Используется для 3D-рендеринга и т. Д. (Может быть отключен, и это связано с составными слоями процесса рендеринга страницы. В последующих статьях, связанных с оптимизацией производительности, снова будет изучаться графический процессор)
Процесс рендеринга в браузере (процесс рендеринга, внутренняя многопоточность): Каждое открытие вкладки создает процесс рендеринга браузера (ядро браузера). По умолчанию на каждую вкладку приходится по одному процессу, и они не влияют друг на друга. Основная функция - отрисовка страницы, выполнение скрипта, обработка событий и т. Д.
Когда браузер был впервые разработан, веб-страницы в то время были очень простыми, а уровень занятости ресурсов каждой веб-страницы был очень низким, поэтому было возможно обрабатывать несколько веб-страниц за один процесс. Тогда сегодня большое количество веб-страниц становятся все более сложными. Браузеры, объединяющие все веб-страницы в один процесс, сталкиваются с проблемами в отношении надежности, скорости отклика и безопасности. Потому что, если страница вкладки в браузере выйдет из строя, это вызовет открытие других веб-приложений. Кроме того, по сравнению с потоками ресурсы и адресное пространство не разделяются между процессами, поэтому не будет слишком много проблем с безопасностью, а поскольку несколько потоков совместно используют одно и то же адресное пространство и ресурсы, могут возникнуть проблемы между потоками. Сложные проблемы безопасности, такие как злонамеренная модификация или получение несанкционированных данных.
Я видел такую картинку в статье Как работает браузер:
Я думаю, что движок браузера соответствует процессу просмотра, а механизм рендеринга соответствует процессу рендеринга.
Чтобы открыть вкладку с пользователем, вы можете увидеть, что сначала контролируется процесс браузера. Затем посмотрим на хромовую модель многопоточности:
Основной метод работы следующий
Процесс браузера получает запрос пользователя, сначала он обрабатывается потоком пользовательского интерфейса, а соответствующая задача передается потоку ввода-вывода, и он случайным образом передает задачу процессу визуализации;
Поток ввода-вывода процесса рендеринга передается потоку рендеринга после простого объяснения. Поток рендеринга получает запрос, загружает веб-страницу и отображает веб-страницу, для чего может потребоваться процесс браузера для получения ресурсов и процесс графического процессора для помощи в рендеринге. Наконец, процесс визуализации передает результат процессу браузера потоком ввода-вывода;
Процесс браузера получает результат и отображает результат;
процесс
С академической точки зрения процесс - это динамическое выполнение программы с определенной независимой функцией в наборе данных. Это независимая единица операционной системы для распределения ресурсов и планирования, а также является носителем прикладных программ. Здесь мы сравниваем процесс с цехом фабрики, который представляет собой единственную задачу, которую может решить ЦП. В любое время ЦП всегда запускает процесс, а другие процессы не выполняются.
В ранних операционных системах не было концепции потоков. Процесс был наименьшей единицей, способной владеть ресурсами и работать независимо, а также наименьшей единицей выполнения программы. Планирование задач использует метод упреждающего планирования ротации квантов времени, и процесс является наименьшей единицей планирования задач.Каждый процесс имеет свой собственный независимый участок памяти, так что адреса памяти каждого процесса изолированы друг от друга. Позже, с развитием компьютеров, требования к ЦП становились все выше и выше, а переключение между процессами было слишком дорогостоящим для удовлетворения требований все более сложных программ. Так был изобретен поток, который представляет собой единый последовательный поток управления выполнением программы и наименьшую единицу потока выполнения программы. Здесь мы сравниваем потоки с рабочими в мастерской, то есть мастерская может позволить нескольким работникам выполнить задачу в сотрудничестве.
Ядра и наборы команд
Одноядерные процессоры не заточены под многопоточность, это означает, что они не могут выполнять множество процессов эффективно и параллельно. Наличие виртуальных ядер типа Hyper-Threading не равносильно наличию двух ядер — все равно поочередно используются ресурсы одного и того же ядра, просто чуть в более оптимизированном порядке. Это приводит к проблемам, когда запущено много приложений, а разные приложения еще и создают несколько потоков. Особенно это хорошо заметно на процессорах Intel Atom и аналогичных.
Наборы команд Intel SSE4.1, Intel SSE4.2, Intel AVX2 также очень важны для увеличения производительности, особенно при работе с мультимедиа. Эти команды, поддержка которых реализована аппаратно, позволяют выполнять различные операции с плавающей запятой быстрее, задействуя меньше ресурсов процессора. Однако, эти команды не используются в коде работы браузера.
Также относительно недавно появилась поддержка технологии Intel TSX-NI. Она появилась в процессорах Intel Core 4-го поколения (2014 г.) и подразумевает под собой надстройку над си стемой работы с кэшем процессора, оптимизирующую среду исполнения многопоточных приложений, но, конечно, только в том случае, если эти приложения используют программные интерфейсы TSX-NI. Соответственно, приложения, чей код написан с учетом этого набора команд, будут работать значительно быстрее.
TSX работает поверх механизма кешей. У cache line появляется дополнительный бит — что этот cache line в данный момент используется транзакцией. Поток начинает транзакцию специальной инструкцией. После этого и до комита транзакции все операции, работающие с памятью, помечают соответствующий cache line как участвующий в транзакции. А если соответствующий cache line уже занят другой транзакцией, то процессор делает переход по специальному адресу, который задаётся в начале транзакции.
Процессоры Intel новых поколений поддерживают Intel Speed Shift Technology. Эта технология использует контролируемые состоянии энергопотребления процессора (P-states) и позволяет динамически частотой ядра, напряжением питания и энергопотребления. Это очень серьезно влияет на производительность однопоточных и кратковременных задач, таких как поток, созданный закладкой браузера. Эта функция появилась в 2015 году и доступна только на процессорах с архитектурой Skylake и более новых.
Поток рендеринга GUI
Отвечает за рендеринг интерфейса браузера, парсинг HTML, CSS, построение дерева DOM и дерева RenderObject, макет и рисование и т. Д.
Когда интерфейс необходимо перерисовать (перерисовать) или вызвать перекомпоновку операции (перекомпоновку), поток будет выполняться
Обратите внимание, что поток визуализации графического интерфейса пользователя и поток механизма JS являются взаимоисключающими. Когда механизм JS выполняется, поток графического интерфейса пользователя приостанавливается (эквивалентно замораживанию), а обновление графического интерфейса пользователя сохраняется в Очередь выполняется немедленно, когда движок JS простаивает.
= Шаг 3. Чтение ответа
Как только тело ответа (payload, полезная нагрузка) начинает поступать, *сетевой-поток при необходимости смотрит на первые несколько байт данных. В заголовке ответа 'Content-Type' должно быть указано, какой это тип данных, но так как он может отсутствовать или быть неправильным, то в данном случае выполняется прослушивание MIME-типа. Это "сложное дело", прокомментировано в исходном коде. Вы можете прочитать эти комментарии исходного кода, чтобы посмотреть, как разные браузеры обращаются с парами 'content-type/payload'
Рисунок 3: Заголовок ответа, содержащий Content-Type и полезную нагрузку, которая является фактическими данными
Если ответ является HTML-файлом, то следующим шагом будет передача данных в *рендер-процесс, но если это zip-файл или какой-либо другой файл, то это означает, что это запрос на загрузку, поэтому он будет передан в менеджер загрузок.
Рисунок 4: *Сетевой-поток спрашивает, являются ли данные ответа HTML данными с безопасного сайта
Здесь также выполняется проверка SafeBrowsing. Если домен и ответные данные, похоже совпадают с известным вредоносным сайтом, то *сетевой-поток предупреждает показом предупреждающей страницы. Кроме того, выполняется проверка Cross Origin Read Blocking (CORB), чтобы убедиться, что конфиденциальные межсайтовые данные не попадают в *рендер-процесс.
= Шаг 2. Старт навигации
Когда пользователь нажимает Enter, *UI-поток инициирует сетевой вызов для получения контента сайта. В углу вкладки отображается анимация загрузки, и *сетевой-поток проходит через соответствующие протоколы, такие как DNS поиск и создание TLS соединения для запроса.
Многопоточность браузера и однопоточность движка js
Резьба триггера синхронизации
Поток, в котором расположены легендарные setInterval и setTimeout
Счетчик времени браузера не подсчитывается механизмом JavaScript (поскольку механизм JavaScript является однопоточным, если он находится в состоянии заблокированного потока, это повлияет на точность отсчета времени)
Таким образом, отдельный поток используется для отсчета времени и запуска отсчета времени (после завершения отсчета времени он добавляется в очередь событий и выполняется после того, как механизм JS простаивает).
Обратите внимание, что W3C устанавливает в стандарте HTML, что временной интервал меньше 4 мс в setTimeout должен считаться 4 мс.
(2) Будет ли WebWorker вызывать многопоточность js?
Сначала приведите пример, вы можете просмотретьweb worker:
Затем откройте панель производительности для просмотра:
Синий прямоугольник на картинке - это браузер после загрузки файла wokder.js. Затем мы можем увидеть красное поле DedicatedWorker Thread, выполнить worker.js во время рабочего потока, затем вернуть вычисленный результат в основной поток и, наконец, выполнить его в синем поле.
Кажется, это создает новую тему. Если бы я не использовал веб-воркеров, DedicatedWorker Thread вообще бы не существовал.
Это не кажется убедительным. Посмотрим еще на одинпример, При локальном просмотре этого примера я скорректировал конкретные числа для достижения эффекта, показанного ниже.
Как показано на рисунке, когда выполняется код setTimeout, также выполняется код worker.js. В результате я получил то, что webworker может выполнять другой код, когда js-движок выполняет код.
Здесь нам нужно с самого начала прояснить проблему, будь то многопоточность, вызванная выполнением js, или многопоточность движка js. Вот две концепции. Основной столбец на приведенном выше рисунке - это процесс рендеринга браузера (я полагаю), потому что в этом процессе мы можем видеть выполнение js-кода, а также есть поток рендеринга графического интерфейса для синтаксического анализа HTML-кода. Теперь я вижу, что поток DedicatedWorker находится на том же уровне, что и процесс рендеринга в браузере (конечно, все они выполняются производительностью, чтобы показать нам).
Я видел предложение на MDN: рабочий интерфейс будет генерировать настоящие потоки на уровне операционной системы. Таким образом, веб-воркер здесь не новичок в js-движке. Это поток на уровне операционной системы. Выполнение потока не повлияет на выполнение исходного движка js и не повлияет на процесс отрисовки в браузере. Что касается его внутренней реализации, я недосягаем. Однако веб-воркер реализует многопоточность выполнения js-кода (конечно, это мои догадки, основанные на результатах, которые я видел, и я не нашел фактических данных аргументации. Если вы знаете, вы можете сказать, спасибо).
Итак, вывод, который я сделал: webworker может вызывать многопоточное выполнение js-кода, но не многопоточное выполнение js-движка. Жизненный цикл webwoker контролируется потоком js-движка, потому что webweoker предоставляет нам серию API-интерфейсов для работы.
Затем давайте поговорим о некотором неработающем контенте в webweoker: также из соображений безопасности, если вы не будете осторожны, параллелизм окажет интересное влияние на ваш код. Однако для веб-воркеров точки взаимодействия с другими потоками тщательно контролируются, а это означает, что вам сложно вызвать проблемы параллелизма. Итак, webworker ввел свои собственные ограничения (следующий контент можно найти в Интернете, потому что я не использовал webworker таким образом):
1. Нет доступа к объектам DOM и BOM, доступ только для чтения к Location и навигатору, а навигатор инкапсулируется в объект WorkerNavigator, изменяя некоторые атрибуты. Не удается прочитать локальную файловую систему
2. Связь между дочерним потоком и родительским потоком осуществляется посредством копирования значения, и изменение содержимого связи дочерним потоком не влияет на основной поток. В процессе связи слишком большое значение также повлияет на производительность (для решения этой проблемы вы можете использовать переносимые объекты)
3. Не совсем многопоточность, многопоточность из-за функции браузера.
4. Совместимость
5 Поскольку поток вводит внешние js через importScripts и выполняет его напрямую, он на самом деле небезопасен, и его легко внедрить некоторый вредоносный код извне.
6. Ограничение количества потоков. Большинство браузеров имеют ограничение на количество потоков, которые могут быть созданы для потоков webworker. Хотя они могут быть расширены вручную, если они не установлены, они обычно находятся в пределах 20 потоков. Каждый поток составляет около 5M. Вручную. Отключите некоторые неиспользуемые потоки, чтобы иметь возможность создавать новые потоки (связанные решения)
7, js имеет реальные потоки, такие как SharedArrayBuffer
= Дополнительный шаг. Завершение начальной загрузки
После реализации навигации *рендер-процесс продолжает загрузку ресурсов и рендеринг страницы. Подробнее о том, что происходит на этом этапе, мы расскажем в следующем посте. Как только *рендер-процесс "финиширует" рендеринг, он посылает IPC запрос обратно в *браузер-процесс (это происходит после того, как все события загрузки сработали на всех фреймах страницы и закончили своё выполнение). На этом этапе *UI-поток останавливает анимацию индикатора загрузки страницы.
Я пишу "финиширует" в кавычках, потому что JavaScript на стороне клиента все равно может загрузить дополнительные ресурсы и вывести новые представления после этого момента.
Рисунок 7: IPC-запрос от *рендер-процесса к *браузер-процессу для уведомления о том, что страница "загружена".
Простая навигация была завершена! Но что случится, если пользователь снова поместит другой URL в адресную строку? Что ж, процесс браузера пройдет те же самые этапы, что и при переходе на другой сайт. Но перед тем, как это сделать, ему нужно проверить для текущего отрисованного сайта, волнует ли его событие beforeunload.
beforeunload может создавать высплыавющее предупреждение "Покинуть этот сайт?" при попытке навигации наружу или закрытии вкладки. Все внутренние вкладки, включая ваш JavaScript код, обрабатывается *рендер-процессом, поэтому *браузер-процесс должен свериться с текущим *рендер-процессом, когда приходит новый навигационный запрос.
Внимание: Не добавляйте без необходмости обработчики beforeunload. Это создает дополнительные задержки, так как обработчик должен быть выполнен еще до того, как навигация может быть запущена. Этот обработчик событий должен добавляться только при необходимости, например, если необходимо предупредить пользователей о том, что они могут потерять данные, введенные на странице.
Рисунок 8: IPC-запрос от *браузер-процесса к *рендер-процессу, говорящий ему, что он собирается перейти на другой сайт
Если навигация была инициирована из *рендер-процесса (например, пользователь нажал на ссылку или JavaScript на стороне клиента запустил window.location = "https://newsite.com" ), то *рендер-процесс сначала проверяет обработчики beforeunload . Затем он проходит через тот же процесс, что и процесс запуска навигации. Единственное отличие состоит в том, что запрос на навигацию запускается от *рендер-процесса к *браузер-процессу.
Когда новая навигация осуществляется на сайт, отличный от текущего, вызывается отдельный *рендер-процесс для обработки новой навигации, в то время как текущий *рендер-процесс продолжается для обработки таких событий, как выгрузка. Для получения более подробной информации смотрите обзор состояния жизненного цикла страницы и то, как вы можете подключаться к событиям с помощью Page Lifecycle API.
Рисунок 9: 2 IPC-запроса от *браузер-процесса к новому *рендер-процессу, говорящему отрисовать страницу и говорящему старому *рендер-процессу выгрузить страницу
Одним из недавних изменений в процессе навигации является введение service worker. *Сервис-воркер — это способ написания сетевого прокси в коде вашего приложения; позволяющий веб-разработчикам иметь больше контроля над тем, что кэшировать локально а когда получать новые данные из сети. Если *сервис-воркер настроен на загрузку страницы из кэша, то нет необходимости запрашивать данные из сети.
Важно помнить, что *сервис-воркер — это JavaScript-код, который запускается в *рендер-процессе. Но когда приходит запрос на навигацию, как *браузер-процессу узнать что у сайта есть *сервис-воркер?
Рисунок 10: Сетевой-поток в процессе просмотра браузером скоупа \сервис-воркера
Рисунок 11: *UI-поток в *браузер-процессе запускает *рендер-процесс для работы с *сервис-воркерами; поток *сервис-воркера в *рендер-процессе затем запрашивает данные из сети
Рисунок 12: *UI-поток в *браузер-процессе, запускающий *рендер-процесс для обработки *сервис-воркера с параллельным запуском сетевого запроса
(1) Процесс и поток
= Шаг 3. Поиск *рендер-процесса
После того, как все проверки завершены и *сетевой-поток уверен, что браузер может перейти к запрашиваемому сайту, *сетевой-поток сообщает *UI-потоку, что данные готовы. Затем *UI-поток ищет *рендер-процесс для продолжения рендеринга веб-страницы.
Рисунок 5: *Сетевой-поток, просящий *UI-поток предоставить *рендер-процесс
Поскольку сетевой запрос на получение обратного ответа может занять несколько сотен миллисекунд, применяется оптимизация для ускорения этого процесса. Когда *UI-поток посылает URL запрос в *сетевой-поток на шаге 2, он уже знает, к какому сайту он обращается. *UI-поток пытается проактивно найти или запустить *рендер-процесс параллельно с сетевым запросом. Таким образом, если все пойдет как ожидалось, *рендер-процесс уже будет находиться в режиме ожидания, к моменту когда *сетевой-поток получил данные. Этот резервный процесс может быть не использован, если навигация будет перенаправлена на другой сайт, в этом случае может потребоваться другой процесс.
Самые быстрые браузеры
Скорость работы всех браузеров разная. На данный момент самыми быстрыми браузерами являются Opera и Mozilla Firefox. Google Chrome в последних версиях стал гораздо «тяжелее», а Firefox — наоборот. Меньше всего в памяти занимает Opera (разница достигает сотен мегабайт).
Если вам все это не помогло, или у вас совсем старый и слабый компьютер (до появления Intel Core), то вам придется использовать использовать специальные прощенные альтернативные браузеры:
В этой серии, состоящей из 4 частей, мы рассмотрим внутренности браузера Chrome от архитектуры высокого уровня до особенностей пайплайна рендеринга. Если вы когда-нибудь задумывались над тем, как браузер превращает ваш код в функциональный сайт, или не знаете, почему для повышения производительности предлагается та или иная методика, то эта серия статей для вас.
- в ходе перевода, я старался вычленять из статьи ПОНЯТИЯ, т.е. текстовые единицы которые несут специальный (технический) смысл. В переводе эти понятия выделены по особенному — во первых понятия предваряются символом звёздочки, во-вторых в них вместо пробела используется тире. Например: *браузер-процесс, *сайто-изоляция. При переводе понятий, приоритет отдавался не красоте перевода, а желанию выделить, акцентировать, то что мы имеем дело с ПОНЯТИЕМ, а не с фигурой речи.
- также, некоторые слова переведены неверно с точки зрения русского языка, в жаргонном стиле, например пайплайн, продакшен. У "технарей" такой перевод не вызовет затруднений, у остальных читателей прошу прощения.
В первой части этой серии мы рассмотрим основную компьютерную терминологию и многопроцессорную архитектуру Chrome.
Примечание: Если вы знакомы с идеей CPU/GPU и процессами/потоками, вы можете сразу перейти к главе "Архитектура браузера".
Для того, чтобы понять среду, в которой работает браузер, нам необходимо познакомиться с некоторыми элементами компьютера и с тем что они делают.
Рис.1: 4 ядра CPU похожи на офисных работников сидящих каждый за своим столом и выполняющих задачи по мере их поступления
Графический процессор — или GPU — это еще одна часть компьютера. В отличие от CPU, GPU хорошо справляется с простыми задачами, но на нескольких ядрах одновременно. Как следует из названия, он изначально разрабатывался для работы с графикой. Именно поэтому в контексте графики "использование GPU" или "GPU-поддержки" ассоциируется с быстрым рендерингом и плавным взаимодействием. В последние годы, благодаря ускорению вычислений на GPU, все больше и больше вычислений становятся возможными только на GPU.
Рис.2: Множество GPU ядер с гаечным ключём олицетворяют что они могут выполнять ограниченные задачи
Когда вы запускаете приложение на вашем компьютере или телефоне, CPU и GPU являются единственными двигателями приложения. Обычно приложения запускаются на CPU и GPU с помощью механизмов, предоставляемых операционной системой.
Рис.3: Три уровня компьютерной архитектуры. Оборудование внизу, Операционная система в середине, и Приложение на верху
Другие понятия, которые нужно понять, прежде чем погружаться в архитектуру браузера — это "Процессы" и "Потоки". Процесс можно представить как выполняющуюся программу приложения. Поток — это такая жизнь внутри процесса которая выполняет какую-либо часть этой программы.
При запуске приложения создается процесс. Программа может создать поток (потоки), чтобы помочь ей в работе, но это опционально. Операционная система предоставляет процессу "область" памяти для работы, и все состояния приложения хранятся в этой приватной области памяти. Когда вы закрываете приложение, процесс также исчезает, и операционная система освобождает память.
Рис.4: Процесс как прямоугольник, потоки как абстрактная рыба плавающая внутри процесса
Рис.5: Диаграмма показывающая использование памяти и хранения данных приложения
Процесс может попросить операционную систему развернуть другой процесс для выполнения различных задач. Когда это происходит, для нового процесса выделяется другая часть памяти. Если двум процессам необходимо общаться, они могут сделать это с помощью межпроцессного взаимодействия (IPC). Многие приложения разработаны таким образом, что если worker процесс не реагирует, его можно перезапустить, не останавливая другие процессы, выполняющие разные части приложения.
Рис.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 используется несколько *рендер-процессов. В самом простом случае можно представить, что каждая вкладка имеет свой собственный *рендер-процесс. Допустим, у вас открыто 3 вкладки, и каждая из них запускается с независимым *рендер-процессом. Если одна из вкладок становится неотзывчивой, то можно закрыть её и двигаться дальше, сохранив при этом другие вкладки. Если все вкладки выполняются в одном процессе, то когда одна из них становится неотзывчивой, становятся неотзывчивыми и все остальные. Это не радует.
Рис.10: Схема показывающая несколько процессов работающих отдельно для каждой вкладки
Еще одним преимуществом разделения работы браузера на несколько процессов является безопасность и изолирование. Поскольку операционные системы обеспечивают способ ограничения привилегий процессов, браузер может изолировать определенные процессы от определенных функций. Например, браузер Chrome ограничивает произвольный доступ к файлам для процессов, обрабатывающих произвольный пользовательский ввод, таких как *рендер-процессы.
Поскольку процессы имеют собственное приватное пространство памяти, они часто содержат копии общей инфраструктуры (например, V8, который является JavaScript-движком Chrome). Это означает большее использование памяти, поскольку они не могут совместно использоваться так, как если бы они были потоками внутри одного и того же процесса. Чтобы сэкономить память, Chrome устанавливает ограничение на то, сколько процессов он может разворачивать. Ограничение варьируется в зависимости от того, сколько памяти и мощности процессора у вашего устройства, и когда Chrome преодолевает это ограничение, он начинает запускать вкладки одного и того же сайта в одном процессе.
Такой же подход применяется и к *браузер-процессу. Chrome претерпел архитектурные изменения для запуска каждой части браузерной программы как сервиса, позволяющие легко разбиваться на разные процессы или объединять их в один.
Общая идея заключается в том, что когда Chrome работает на мощном аппаратном обеспечении, он может разделить каждый сервис на разные процессы, давая бОльшую стабильность, но если он работает на устройстве, с ограниченными ресурсами, то Chrome консолидирует сервисы в один процесс, экономя память. Аналогичный подход к консолидации процессов для меньшего использования памяти используется так же в Android.
Рисунок 11: Схема сервисности Chrome, на которой различные сервисы переносятся в несколько процессов и наоборот в один *бразуер-процесс
Рисунок 12: Схема *сайто-изоляции; несколько *рендер-процессов используются для iframes внутри сайта
Создание *сайто-изоляции стало результатом многолетней инженерной работы. Изоляция сайта не так проста, как использование разных *рендер-процессов; она принципиально меняет способ общения iframes друг с другом. Открытие devtools на странице с iframes, запущенными на разных процессах, означает, что devtools должен был реализовать фоновую работу, чтобы это выглядело незаметно. Даже запуск простого Ctrl+F для поиска слова на странице означает поиск по различным *рендер-процессам. Теперь вы можете понять причину, по которой разработчики браузеров говорят о реализации *сайто-изоляции как о важной вехе!
В этом посте мы сделали высокоуровневый взгляд на архитектуру браузера и преимущества многопроцессорной архитектуры. Мы также рассказали о сервисности и *сайт-изоляции в Chrome, которая тесно связана с многопроцессорной архитектурой. В следующем посте мы начнем размышлять о том, как взаимодействуют процессы и потоки, чтобы отобразить веб-сайт.
Это 2-я часть из 4-х, в которой рассматривается внутренняя работа Chrome. В предыдущей части мы рассмотрели, как различные процессы и потоки работают с разными частями браузера. В этом посте мы подробнее рассмотрим, как каждый процесс и поток взаимодействуют, чтобы отобразить веб-сайт.
- в ходе перевода, я старался вычленять из статьи ПОНЯТИЯ, т.е. текстовые единицы которые несут специальный (технический) смысл. В переводе эти понятия выделены по особенному — во первых понятия предваряются символом звёздочки, во-вторых в них вместо пробела используется тире. Например: *браузер-процесс, *сайто-изоляция. При переводе понятий, приоритет отдавался не красоте перевода, а желанию выделить, акцентировать, то что мы имеем дело с ПОНЯТИЕМ, а не с фигурой речи.
- также, некоторые слова переведены неверно с точки зрения русского языка, в жаргонном стиле, например пайплайн, продакшен. У "технарей" такой перевод не вызовет затруднений, у остальных читателей прошу прощения.
Рассмотрим простой пример использования веб-браузера: вы вводите URL в браузере, затем браузер извлекает данные из интернета и отображает страницу. В этой заметке мы остановимся на той части, где пользователь запрашивает сайт, а браузер готовится к отображению страницы — также известной как навигация.
Как мы описывали в первой части, все, что находится вне вкладки, обрабатывается *браузер-процессом. *Браузер-процесс имеет такие потоки, как *UI-поток (UI thread), который рисует кнопки и поля ввода браузера, *сетевой-поток (network thread), который имеет дело с сетевым стеком для получения данных из Интернета, *поток-хранения (storage thread), который контролирует доступ к файлам и многие другие. Когда вы вводите URL в адресную строку, ваш ввод обрабатывается *UI-потоком *браузер-процесса.
Рисунок 1: Интерфейс браузера вверху, схема *браузер-процесса с *UI-потоком, *сетевым-потоком и *потоком-хранения внутри внизу
Читайте также: