Движок quantum что это
Firefox 57 «Quantum». Что нужно знать о новой версии
Firefox 57 (Quantum) представляет собой результат длительной работы компании Mozilla по устранению предыдущих проблем браузера, в частности невысокой скорости работы и частым сбоям. Эти и другие недостатки в свою очередь привели к серьезной потере пользовательской базы.
Однако столь глобальные изменения браузера могут создавать дополнительные проблемы для пользователей Firefox. Перед обновлением до Firefox 57 важно знать и учитывать ряд важных моментов.
Проблемы с дополнениями. Устаревшие расширения
Новая платформа API WebExtensions совместима со стандартом WebExtensions, который поддерживается браузерами на базе Chromium (Chrome, Vivaldi, Opera) и новым браузером Microsoft Edge. Это означает, что многие разработчики расширений для Chrome могут адаптировать свои продукты для работы в Firefox.
Mozilla объявила о начале работ по реализации поддержки WebExtensions API еще летом 2015 года, a в августе 2016 года уже представила новое API с релизом Firefox 48.
Начиная с версии 57, Firefox будет поддерживать только расширения, построенные на новом API, и полностью откажется от старой технологии на базе XUL, унаследованной от проекта Netscape.
Таким образом, уже на следующей неделе пользователям Firefox придется искать альтернативы для устаревших дополнений, созданных на старом SDK.
На следующей неделе Mozilla изменит портал “Дополнения Firefox”, чтобы на нем по умолчанию отображались только совместимые с WebExtensions плагины. В настоящее время только около 6000 из более 20 000 дополнений Firefox были перенесены на новый API. Это означает, что для некоторых расширений альтернативы может не найтись.
Вы можете подобрать альтернативы с поддержкой WebExtensions прямо сейчас, используя тег Firefox57 на портале дополнений Mozilla.
Что касается процедуры перехода, то после обновления до Firefox 57 в списке дополнений будут показываться только плагины на WebExtensions. Классические расширения будут перенесены в новый раздел “Устаревшие расширения”. Скриншот ниже наглядно это демонстрирует:
Новый движок
Firefox 57 также станет первой версией Firefox, поддерживающей новый браузерный движок Quantum. Анонсированный в прошлом году, движок Quantum заменяет некоторые части старого Gecko новыми компонентами, написанными на Rust и C ++.
Процесс медленной замены частей Gecko начался в прошлом году, в ситуации, которую инженеры Mozilla назвали “заменой реактивного двигателя, когда самолет все еще находится в полете”.
Mozilla поставила свой первый компонент Rust прошлым летом, заменив стеки медиафайлов Firefox на модуль Rust, а в августе этого года заменила CSS движок Gecko на Quantum CSS (Stylo).
Firefox 57 будет включать в себя еще больше кода Project Quantum. Новая версия браузера получит Quantum Render, новый, оптимизированный для графического процессора конвейер рендеринга на основе проекта WebRender от Servo, и новый метод Quantum DOM Scheduler, который гарантирует, что фоновые вкладки не смогут замедлить работу активных вкладок браузера.
Mozilla утверждает, что все эти внутренние изменения привели к значительному увеличению скорости загрузки страниц и работы браузера Firefox в целом, хотя это утверждение следует воспринимать с изрядной долей скепсиса, поскольку все разработчики браузеров говорят то же самое, когда запускают новую версию.
Новый интерфейс
Кроме нового движка, Firefox 57 получит новый пользовательский интерфейс, построенный на базе проекта Project Photon.
Project Photon серьезно обновляет интерфейс веб-браузера, добавляет новые панели настроек, новую страницу вкладок и новые боковые панели.
Кроме того, начиная с Firefox 57, новые версии Firefox будут поставляться с отключенным виджетом поиска, который раньше отображался в верхнем правом углу старого UI Firefox и являлся знаковой его частью. С положительной стороны, при желании, пользователи могут повторно включить старый виджет поиска на панели настроек.
Запланированные изменения пользовательского интерфейса, скорее всего, будут раздражать некоторых пользователей Firefox, потому что дополнение Classic Theme Restorer Firefox также перестанет работать, то есть пользователи не смогут контролировать внешний вид браузера.
Если вам не нравится новый пользовательский интерфейс, возможно, стоит обратить внимание на другие браузеры. Пользователи могут предварительно ознакомиться с новым интерфейсом, установив Firefox Nightly.
Помимо этих глобальных изменений, в Firefox 57 получит небольшие улучшения, такие как, к примеру, возможность включать защиту от отслеживания на постоянной основе.
Firefox Quantum, что это за движок и какие у него преимущества?
Что это такое — Firefox Quantum? Это настоящий прорыв для разработчиков Mozilla, ведь это движок для браузера нового поколения. В общем, давайте разбираться.
Насколько Firefox подвергся изменениям в новой интерпретации Quantum?
Новое исполнение интерфейса Firefox
В представленной версии «Лисы» в интерфейсе подверглось изменению практически все, что сделало рабочее пространство более «строгим» и «приятным» при восприятии:
Расширения WebExtensions с новыми API
Переход плагинов и расширений на WebExten s ion — это приоритет в разработке для браузеров.
Расширенный набор инструментария для разработчиков
Firefox Quantum — это то, что помогает работать программистам эффективнее. Потому что весь пакет инструментов перешел на новый уровень и обзавелся новой функциональностью в:
Новые правила в защищенности и приватности
Движок Firefox Quantum
Стало заметно, что при работе с большим количеством открытых вкладок браузер тоже стал работать быстрее, переключение между вкладками почти мгновенное. В целом над нов ым браузер ом была проведена колоссальная работа по оптимизации систем, поэтому Mozilla удалось достичь очень низкого уровня потребления ОЗУ. При сравнении с тем же Хромом «Лиса» использует на 30% меньше ОЗУ.
Стоит ли апгрейдиться до Firefox Quantum
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Firefox Quantum
Квантум – это название нового движка, который используется в последних версиях браузера Фаерфокс. Он пришел на замену по всем параметрам устаревшего Gecko, а случилось это в конце 2018 года. Для пользователей «Огненной лисицы» данная инновация пошла только на пользу. Давайте разберемся с ключевыми особенностями Mozilla Firefox Quantum и нюансами использования интернет-обозревателя.
Подробности
На официальном сайте разработчики обозначили следующие достоинства нового движка:
Теперь вам известны ключевые достоинства движка Фаерфокс Квантум. Далее мы разберем процедуру установки браузера для разных ОС.
Инсталляция
В настоящий момент новая «Огненная лисица» поддерживается не только на компьютерах с операционной системой Windows. Она также доступна для Linux и Mac OS. По этой причине мы разобрали каждый из трех случаев по отдельности и подготовили три отдельных руководства.
Руководство №1: Windows
Сначала перейдите на страницу загрузки. На ней кликните по зеленой кнопке и сохраните файл Firefox Installer.exe.

Руководство №2: Linux
Удобнее всего загружать актуальную версию Фаерфокса с помощью Терминала. Предлагаем вам пошаговую инструкцию:
Руководство №3: Mac OS
На «яблочных» ПК процедура инсталляции предельно простая:
Внутри супер-быстрого CSS-движка: Quantum CSS (aka Stylo)
Привет, Хабр! Представляю вашему вниманию перевод статьи Inside a super fast CSS engine: Quantum CSS (aka Stylo) автора Лин Кларк.
Вы возможно слышали о Project Quantum… Это проект по существенной переработке внутренностей Firefox с целью ускорить браузер. По частям мы внедряем наработки нашего экспериментального браузера Servo и значительно улучшаем остальные элементы движка.
Проект сравнивался с заменой самолетного двигателя на лету. Мы вносим изменения в Firefox компонент за компонентом, так что оценить их эффект можно в очередном релизе браузера сразу по готовности.
Прим. переводчика: под катом много иллюстраций. Все они кликабельные (для просмотра в большем разрешении). Если Вы наткнетесь на неточности перевода и другие ошибки — буду благодарен, если сообщите об этом в комментариях или в личку.
Новый движок воплощает лучшие инновации из других браузеров.
Quantum CSS использует преимущества современного железа, распараллеливая работу между всеми ядрами процессора, что дает ускорение вплоть до 2, 4 или даже 18 раз.
Кроме того, он комбинирует современные оптимизации из других браузеров, так что даже без распараллеливания он очень быстрый.
Но чем конкретно занимается CSS-движок? Для начала давайте рассмотрим что такое движок CSS в целом и каково его место в браузере, а после разберём, как Quantum CSS все это дело ускоряет.
Что такое CSS-движок?
CSS-движок — это часть движка рендеринга браузера. Движок рендеринга принимает HTML и CSS файлы сайта и превращает их в пиксели на экране.
Каждый браузер имеет движок рендеринга. У Chrome это Blink, у Edge — EdgeHTML, у Safari — WebKit, ну а у Firefox — Gecko.
Чтобы переварить файлы в пиксели, все они делают примерно одно и то же:
1) Парсинг файлов в понятные браузеру объекты, включая DOM. На этом этапе DOM знает о структуре страницы, знает о родительских отношениях между элементами, но не знает, как эти элементы должны выглядеть.
2) Определение внешнего вида элементов. Для каждого узла DOM движок CSS выясняет, какие CSS-правила применить. Потом он определяет значение для каждого свойства CSS. Стилизирует каждый узел в DOM-дереве, прикрепляя рассчитанные стили.
3) Определение размеров и положения для каждого узла. Для всего, что должно быть отображено на экране, создаются блоки (boxes). Они представляют не только узлы DOM, но и то, что может быть внутри них. Например, строки текста.
4) Отрисовка блоков. Она может происходить на нескольких слоях. Я представляю это себе, как старые, нарисованные от руки анимации на нескольких листах полупрозрачной бумаги. Это позволяет изменить один слой, без необходимости перерисовывать другие.
5) Объединение слоев в одно изображение, предварительно применив к ним необходимые свойства композитора (например, трансформации). Это как сделать фотографию слоев, совмещенных вместе. Далее это изображение будет отображено на экране.
То есть, перед началом просчёта стилей на входе CSS-движка имеется:
И так, он поочередно определяет стили для каждого узла DOM, одного за другим. Значение назначается каждому свойству CSS, даже если оно не задано в таблицах стилей.
Я представляю это себе, как заполнение формы, где все поля обязательны. Нужно заполнить такую форму для каждого узла DOM.
Чтобы сделать это, CSS-движок должен выполнить две вещи:
Сопоставление селекторов
Для начала, мы выбираем все применяемые к узлу правила в список. Поскольку может быть несколько подходящих правил, возможны несколько определений одного и того же свойства.
Кроме того, браузер сам добавляет некоторые стандартные стили (user agent style sheets). Так как же CSS-движок определяет, какое значение использовать?
Вот где нам приходит на помощь «правило конкретности» (specificity rule). Движок CSS создает таблицу определений, которую потом сортирует по разным столбцам.
Правило с наибольшей конкретностью побеждает. Основываясь на такой таблице, CSS-движок вносит все заданные в ней значения в форму.
Остальные высчитываются за счет каскадирования.
Каскадирование
CSS-движок проверяет незаполненные поля в форме. Если свойство наследуется по умолчанию, то CSS-движок поднимается по дереву и проверяет, задано ли значение этому свойству у родительского элемента. Если ни один из предков значения не определяет, или оно не наследуется, то выставляется значение по умолчанию.
Так что теперь все стили для заданного узла DOM просчитаны, форма заполнена.
Примечание: совместное использование структур стилей
Описанная форма немного упрощена. CSS имеет сотни свойств. Если бы CSS-движок сохранял значение каждого свойства для каждого DOM-узла, он быстро использовал бы всю доступную память.
Вместо этого, движки обычно используют механизм совместного использования структур стилей (style struct sharing). Они сохраняют значения, которые обычно используются вместе (например свойства шрифта) в другом объекте под названием «структура стилей». Далее, вместо хранения всех свойств в одном объекте, объекты рассчитанных стилей содержат только указатель. Для каждой категории свойств существует указатель на структуру стилей с нужными значениями.
Это экономит и память, и время. Узлы с похожими стилями могут просто указывать на те же структуры стилей для общих свойств. И поскольку многие свойства наследуются, родитель может делиться своей структурой с любыми дочерними узлами, которые не переопределяют собственные значения.
Так как же мы все это ускоряем?
Так выглядит неоптимизированный процесс расчёта стилей.
Здесь выполняется достаточно много работы. При чём не только в момент первой загрузки страницы. А снова и снова, по ходу взаимодействия со страницей, при наведении курсора на элементы или изменении DOM вызывается перерасчёт стилей.
Это значит, что вычисление CSS стилей — отличный кандидат для оптимизации… И за последние 20 лет браузеры перетестировали множество разных стратегий оптимизации. Quantum CSS пытается совместить лучшие из них для создания нового супер-быстрого движка.
Давайте рассмотрим, как это всё работает вместе.
Распараллеливание
Проект Servo (из которого вышел Quantum CSS) — это экспериментальный браузер, который пытается распараллелить всё в процессе отрисовки веб-страницы. Что это значит?
Можно сравнить компьютер с мозгом. Есть элемент, отвечающий за мышление (АЛУ). Возле него располагается что-то типа краткосрочной памяти (регистры), последние сгруппированы вместе на центральном процессоре. Кроме того есть долгосрочная память (ОЗУ).
Ранние компьютеры могли думать только одну мысль за раз. Но за последние десятилетия процессоры изменились, теперь они имеют несколько сгруппированных в ядра АЛУ и регистров. Так что теперь процессоры могут думать несколько мыслей одновременно — параллельно.
Quantum CSS использует эти преимущества, разделяя вычисление стилей для разных узлов DOM по разным ядрам.
Может показаться, что это легко… Всего лишь разделить ветви дерева и обрабатывать их на разных ядрах. На самом деле всё гораздо сложнее по нескольким причинам. Первая причина в том, что DOM-деревья часто неравномерные. То есть, одни ядра получат значительно больше работы, чем другие.
Чтобы распределить работу более равномерно Quantum CSS использует технику под названием «воровство работы» (work stealing). Когда узел DOM обрабатывается, программа берет его прямые дочерние элементы и разделяет их на одну или несколько «единиц работы» (work unit). Эти единицы работы ставятся в очередь.
Когда какое-то ядро доделало всю работу в своей очереди, оно может поискать себе работы в других очередях. Таким образом мы равномерно распределяем работу без необходимости предварительной оценки с проходом по всему дереву.
В большинстве браузеров будет сложно реализовать это правильно. Параллелизм — это заведомо сложная задача, а CSS-движок достаточно сложный и сам по себе. Он также находится между двумя другими самыми сложными частями движка рендеринга — DOM и разметки. В общем, ошибку допустить легко, и распараллеливание может привести к достаточно трудноотловимым багам, под названием «гонки данных» (data races). Я описываю эти баги подробнее в другой статье (есть и перевод на русский).
Если Вы принимаете правки от сотен тысяч контрибьюторов, как Вы можете применять параллелизм без страха? Для этого у нас есть Rust.
Rust позволяет статически удостоверится, что гонки данных отсутствуют. То есть, Вы избегаете сложноотловимых багов, не допуская их в Ваш код изначально. Компилятор просто не разрешит Вам это сделать. Я напишу об этом подробнее в будущих статьях. Также Вы можете посмотреть вступительное видео о параллелизме в Rust или этот более детальный разговор о «воровсте работы».
Ускорение перерасчёта с помощью дерева правил
Для каждого DOM-узла CSS-движок должен пройтись по всем правилам и выполнить сопоставление селекторов. Для большинства узлов соответствующие селекторы скорее всего будут меняться не очень часто. К примеру, если пользователь наводит указатель мыши на какой-то элемент, то соответствующие ему правила могут измениться. Нам необходимо пересчитать стили для всех его потомков, чтобы обработать наследование свойств. Но правила, соответствующие этим потомкам, вероятно не изменятся.
Было бы неплохо запоминать, какие правила соответствуют этим потомкам, чтобы не пришлось сопоставлять селекторы снова… И дерево правил, пришедшее из предыдущих версий Firefox, делает именно это.
Движок CSS выбирает селекторы, соответствующие элементу, а потом сортирует их по конкретности (specificity). В результате выходит связанный список правил.
Этот список добавляется в дерево.
CSS-движок пытается минимизировать количество веток в дереве, переиспользуя их, когда возможно.
Если большинство селекторов в списке совпадает с существующей веткой, он проследует по ней. Но он может достичь точки, где следующее правило в списке не совпадает с правилом из существующей ветки. Только в таком случае создается новая ветка.
DOM-узел получит указатель на то правило, которое было добавлено последним (в нашем примере, div#warning ). Оно самое конкретное.
При перерасчёте стилей, движок выполняет быструю проверку, может ли изменение в правилах родительского элемента повлиять на правила дочерних. Если нет, то для всех потомков, движок может просто использовать указатель на соответствующее правило в дереве. То есть, полностью пропустить сопоставление селекторов и сортировку.
И так, это помогает сэкономить время при перерасчёте стилей, но начальный расчет все-равно трудоемкий. Если есть 10000 узлов, то необходимо проделать сопоставление селекторов 10000 раз. Но есть способ ускорить и это.
Ускорение начального рендеринга при помощи общего кеша стилей
Представьте себе страницу с тысячами узлов. Многие из них будут соответствовать тем же правилам. Например, представьте длинную страницу Википедии… Параграфы основного контента должны иметь абсолютно идентичные правила стилей и абсолютно идентичные рассчитанные стили.
Без оптимизаций CSS-движок должен сопоставить селекторы и рассчитать стили для каждого параграфа отдельно. Но если бы был способ доказать, что стили для всех параграфов совпадают, то движок мог бы просто выполнить эту работу один раз, и из каждого узла просто указывать на тот же рассчитанный стиль.
Именно это делает общий кеш правил, черпающий вдохновение из Safari и Chrome. После обработки элемента, рассчитанный стиль ложится в кеш. Далее, перед началом расчёта стилей следующего элемента, выполняются несколько проверок, чтобы проверить, нельзя ли использовать что-то из кеша.
WebKit и Blink в таких ситуациях сдаются и не используют общий кеш стилей. И чем больше сайтов используют эти современные селекторы, тем менее становится польза от такой оптимизации, поэтому команда Blink недавно удалила ее совсем. Но оказывается, что есть возможность поспеть за всеми этими обновлениями и с общим кешем стилей.
В Quantum CSS мы собираем все те странные селекторы и проверяем, применяются ли они к узлу DOM. Потом мы сохраняем результат этой проверки в виде единиц и нолей для каждого такого селектора. Если два элемента имеют идентичный набор единиц и нолей — мы знаем, что они точно совпадают.
Если DOM-узел может использовать стили, которые уже рассчитаны, то по сути почти вся работа пропускается. Страницы часто имеют много узлов с одинаковыми стилями, поэтому общий кеш стилей экономит память и действительно ускоряет работу.
Вывод
Это первый крупный трансфер технологии из Servo в Firefox. Мы многому научились, о том, как вносить современный, высокопроизводительный код на Rust в ядро Firefox.
Мы очень рады, что большой кусок Project Quantum готов для бета-использования. Будем благодарны, если Вы попробуете его и, в случае ошибок, сообщите о них.
О Лин Кларк
Лин — инженер в команде Mozilla Developer Relations. Она работает с JavaScript, WebAssembly, Rust и Servo. А также рисует code cartoons.
Внутри супер-быстрого CSS-движка: Quantum CSS (aka Stylo)
Привет, Хабр! Представляю вашему вниманию перевод статьи Inside a super fast CSS engine: Quantum CSS (aka Stylo) автора Лин Кларк.
Вы возможно слышали о Project Quantum… Это проект по существенной переработке внутренностей Firefox с целью ускорить браузер. По частям мы внедряем наработки нашего экспериментального браузера Servo и значительно улучшаем остальные элементы движка.
Проект сравнивался с заменой самолетного двигателя на лету. Мы вносим изменения в Firefox компонент за компонентом, так что оценить их эффект можно в очередном релизе браузера сразу по готовности.
Прим. переводчика: под катом много иллюстраций. Все они кликабельные (для просмотра в большем разрешении). Если Вы наткнетесь на неточности перевода и другие ошибки — буду благодарен, если сообщите об этом в комментариях или в личку.
Новый движок воплощает лучшие инновации из других браузеров.
Quantum CSS использует преимущества современного железа, распараллеливая работу между всеми ядрами процессора, что дает ускорение вплоть до 2, 4 или даже 18 раз.
Кроме того, он комбинирует современные оптимизации из других браузеров, так что даже без распараллеливания он очень быстрый.
Но чем конкретно занимается CSS-движок? Для начала давайте рассмотрим что такое движок CSS в целом и каково его место в браузере, а после разберём, как Quantum CSS все это дело ускоряет.
Что такое CSS-движок?
CSS-движок — это часть движка рендеринга браузера. Движок рендеринга принимает HTML и CSS файлы сайта и превращает их в пиксели на экране.
Каждый браузер имеет движок рендеринга. У Chrome это Blink, у Edge — EdgeHTML, у Safari — WebKit, ну а у Firefox — Gecko.
Чтобы переварить файлы в пиксели, все они делают примерно одно и то же:
1) Парсинг файлов в понятные браузеру объекты, включая DOM. На этом этапе DOM знает о структуре страницы, знает о родительских отношениях между элементами, но не знает, как эти элементы должны выглядеть.
2) Определение внешнего вида элементов. Для каждого узла DOM движок CSS выясняет, какие CSS-правила применить. Потом он определяет значение для каждого свойства CSS. Стилизирует каждый узел в DOM-дереве, прикрепляя рассчитанные стили.
3) Определение размеров и положения для каждого узла. Для всего, что должно быть отображено на экране, создаются блоки (boxes). Они представляют не только узлы DOM, но и то, что может быть внутри них. Например, строки текста.
4) Отрисовка блоков. Она может происходить на нескольких слоях. Я представляю это себе, как старые, нарисованные от руки анимации на нескольких листах полупрозрачной бумаги. Это позволяет изменить один слой, без необходимости перерисовывать другие.
5) Объединение слоев в одно изображение, предварительно применив к ним необходимые свойства композитора (например, трансформации). Это как сделать фотографию слоев, совмещенных вместе. Далее это изображение будет отображено на экране.
То есть, перед началом просчёта стилей на входе CSS-движка имеется:
И так, он поочередно определяет стили для каждого узла DOM, одного за другим. Значение назначается каждому свойству CSS, даже если оно не задано в таблицах стилей.
Я представляю это себе, как заполнение формы, где все поля обязательны. Нужно заполнить такую форму для каждого узла DOM.
Чтобы сделать это, CSS-движок должен выполнить две вещи:
Сопоставление селекторов
Для начала, мы выбираем все применяемые к узлу правила в список. Поскольку может быть несколько подходящих правил, возможны несколько определений одного и того же свойства.
Кроме того, браузер сам добавляет некоторые стандартные стили (user agent style sheets). Так как же CSS-движок определяет, какое значение использовать?
Вот где нам приходит на помощь «правило конкретности» (specificity rule). Движок CSS создает таблицу определений, которую потом сортирует по разным столбцам.
Правило с наибольшей конкретностью побеждает. Основываясь на такой таблице, CSS-движок вносит все заданные в ней значения в форму.
Остальные высчитываются за счет каскадирования.
Каскадирование
CSS-движок проверяет незаполненные поля в форме. Если свойство наследуется по умолчанию, то CSS-движок поднимается по дереву и проверяет, задано ли значение этому свойству у родительского элемента. Если ни один из предков значения не определяет, или оно не наследуется, то выставляется значение по умолчанию.
Так что теперь все стили для заданного узла DOM просчитаны, форма заполнена.
Примечание: совместное использование структур стилей
Описанная форма немного упрощена. CSS имеет сотни свойств. Если бы CSS-движок сохранял значение каждого свойства для каждого DOM-узла, он быстро использовал бы всю доступную память.
Вместо этого, движки обычно используют механизм совместного использования структур стилей (style struct sharing). Они сохраняют значения, которые обычно используются вместе (например свойства шрифта) в другом объекте под названием «структура стилей». Далее, вместо хранения всех свойств в одном объекте, объекты рассчитанных стилей содержат только указатель. Для каждой категории свойств существует указатель на структуру стилей с нужными значениями.
Это экономит и память, и время. Узлы с похожими стилями могут просто указывать на те же структуры стилей для общих свойств. И поскольку многие свойства наследуются, родитель может делиться своей структурой с любыми дочерними узлами, которые не переопределяют собственные значения.
Так как же мы все это ускоряем?
Так выглядит неоптимизированный процесс расчёта стилей.
Здесь выполняется достаточно много работы. При чём не только в момент первой загрузки страницы. А снова и снова, по ходу взаимодействия со страницей, при наведении курсора на элементы или изменении DOM вызывается перерасчёт стилей.
Это значит, что вычисление CSS стилей — отличный кандидат для оптимизации… И за последние 20 лет браузеры перетестировали множество разных стратегий оптимизации. Quantum CSS пытается совместить лучшие из них для создания нового супер-быстрого движка.
Давайте рассмотрим, как это всё работает вместе.
Распараллеливание
Проект Servo (из которого вышел Quantum CSS) — это экспериментальный браузер, который пытается распараллелить всё в процессе отрисовки веб-страницы. Что это значит?
Можно сравнить компьютер с мозгом. Есть элемент, отвечающий за мышление (АЛУ). Возле него располагается что-то типа краткосрочной памяти (регистры), последние сгруппированы вместе на центральном процессоре. Кроме того есть долгосрочная память (ОЗУ).
Ранние компьютеры могли думать только одну мысль за раз. Но за последние десятилетия процессоры изменились, теперь они имеют несколько сгруппированных в ядра АЛУ и регистров. Так что теперь процессоры могут думать несколько мыслей одновременно — параллельно.
Quantum CSS использует эти преимущества, разделяя вычисление стилей для разных узлов DOM по разным ядрам.
Может показаться, что это легко… Всего лишь разделить ветви дерева и обрабатывать их на разных ядрах. На самом деле всё гораздо сложнее по нескольким причинам. Первая причина в том, что DOM-деревья часто неравномерные. То есть, одни ядра получат значительно больше работы, чем другие.
Чтобы распределить работу более равномерно Quantum CSS использует технику под названием «воровство работы» (work stealing). Когда узел DOM обрабатывается, программа берет его прямые дочерние элементы и разделяет их на одну или несколько «единиц работы» (work unit). Эти единицы работы ставятся в очередь.
Когда какое-то ядро доделало всю работу в своей очереди, оно может поискать себе работы в других очередях. Таким образом мы равномерно распределяем работу без необходимости предварительной оценки с проходом по всему дереву.
В большинстве браузеров будет сложно реализовать это правильно. Параллелизм — это заведомо сложная задача, а CSS-движок достаточно сложный и сам по себе. Он также находится между двумя другими самыми сложными частями движка рендеринга — DOM и разметки. В общем, ошибку допустить легко, и распараллеливание может привести к достаточно трудноотловимым багам, под названием «гонки данных» (data races). Я описываю эти баги подробнее в другой статье (есть и перевод на русский).
Если Вы принимаете правки от сотен тысяч контрибьюторов, как Вы можете применять параллелизм без страха? Для этого у нас есть Rust.
Rust позволяет статически удостоверится, что гонки данных отсутствуют. То есть, Вы избегаете сложноотловимых багов, не допуская их в Ваш код изначально. Компилятор просто не разрешит Вам это сделать. Я напишу об этом подробнее в будущих статьях. Также Вы можете посмотреть вступительное видео о параллелизме в Rust или этот более детальный разговор о «воровсте работы».
Ускорение перерасчёта с помощью дерева правил
Для каждого DOM-узла CSS-движок должен пройтись по всем правилам и выполнить сопоставление селекторов. Для большинства узлов соответствующие селекторы скорее всего будут меняться не очень часто. К примеру, если пользователь наводит указатель мыши на какой-то элемент, то соответствующие ему правила могут измениться. Нам необходимо пересчитать стили для всех его потомков, чтобы обработать наследование свойств. Но правила, соответствующие этим потомкам, вероятно не изменятся.
Было бы неплохо запоминать, какие правила соответствуют этим потомкам, чтобы не пришлось сопоставлять селекторы снова… И дерево правил, пришедшее из предыдущих версий Firefox, делает именно это.
Движок CSS выбирает селекторы, соответствующие элементу, а потом сортирует их по конкретности (specificity). В результате выходит связанный список правил.
Этот список добавляется в дерево.
CSS-движок пытается минимизировать количество веток в дереве, переиспользуя их, когда возможно.
Если большинство селекторов в списке совпадает с существующей веткой, он проследует по ней. Но он может достичь точки, где следующее правило в списке не совпадает с правилом из существующей ветки. Только в таком случае создается новая ветка.
DOM-узел получит указатель на то правило, которое было добавлено последним (в нашем примере, div#warning ). Оно самое конкретное.
При перерасчёте стилей, движок выполняет быструю проверку, может ли изменение в правилах родительского элемента повлиять на правила дочерних. Если нет, то для всех потомков, движок может просто использовать указатель на соответствующее правило в дереве. То есть, полностью пропустить сопоставление селекторов и сортировку.
И так, это помогает сэкономить время при перерасчёте стилей, но начальный расчет все-равно трудоемкий. Если есть 10000 узлов, то необходимо проделать сопоставление селекторов 10000 раз. Но есть способ ускорить и это.
Ускорение начального рендеринга при помощи общего кеша стилей
Представьте себе страницу с тысячами узлов. Многие из них будут соответствовать тем же правилам. Например, представьте длинную страницу Википедии… Параграфы основного контента должны иметь абсолютно идентичные правила стилей и абсолютно идентичные рассчитанные стили.
Без оптимизаций CSS-движок должен сопоставить селекторы и рассчитать стили для каждого параграфа отдельно. Но если бы был способ доказать, что стили для всех параграфов совпадают, то движок мог бы просто выполнить эту работу один раз, и из каждого узла просто указывать на тот же рассчитанный стиль.
Именно это делает общий кеш правил, черпающий вдохновение из Safari и Chrome. После обработки элемента, рассчитанный стиль ложится в кеш. Далее, перед началом расчёта стилей следующего элемента, выполняются несколько проверок, чтобы проверить, нельзя ли использовать что-то из кеша.
WebKit и Blink в таких ситуациях сдаются и не используют общий кеш стилей. И чем больше сайтов используют эти современные селекторы, тем менее становится польза от такой оптимизации, поэтому команда Blink недавно удалила ее совсем. Но оказывается, что есть возможность поспеть за всеми этими обновлениями и с общим кешем стилей.
В Quantum CSS мы собираем все те странные селекторы и проверяем, применяются ли они к узлу DOM. Потом мы сохраняем результат этой проверки в виде единиц и нолей для каждого такого селектора. Если два элемента имеют идентичный набор единиц и нолей — мы знаем, что они точно совпадают.
Если DOM-узел может использовать стили, которые уже рассчитаны, то по сути почти вся работа пропускается. Страницы часто имеют много узлов с одинаковыми стилями, поэтому общий кеш стилей экономит память и действительно ускоряет работу.
Вывод
Это первый крупный трансфер технологии из Servo в Firefox. Мы многому научились, о том, как вносить современный, высокопроизводительный код на Rust в ядро Firefox.
Мы очень рады, что большой кусок Project Quantum готов для бета-использования. Будем благодарны, если Вы попробуете его и, в случае ошибок, сообщите о них.
О Лин Кларк
Лин — инженер в команде Mozilla Developer Relations. Она работает с JavaScript, WebAssembly, Rust и Servo. А также рисует code cartoons.



