Вы когда-нибудь задумывались о том, какой объем работы выполняет CSS? Вы меняете один атрибут, и внезапно весь ваш сайт выглядит по-другому. Это своего рода магия . До сих пор мы — сообщество веб-разработчиков — могли только наблюдать и быть свидетелями магии. А что, если мы хотим придумать свою собственную магию? А что, если мы хотим стать волшебником ?
Появляется Гудини!
Целевая группа Houdini состоит из инженеров из Mozilla, Apple, Opera, Microsoft, HP, Intel и Google, которые работают вместе, чтобы представить определенные части движка CSS веб-разработчикам. Целевая группа работает над коллекцией проектов с целью их принятия W3C, чтобы они стали фактическими веб-стандартами. Они поставили перед собой несколько высокоуровневых целей, превратили их в проекты спецификаций, которые в свою очередь породили набор вспомогательных проектов спецификаций более низкого уровня.
Коллекция этих черновиков — это то, что обычно подразумевают, когда говорят о "Гудини". На момент написания статьи список черновиков неполный, а некоторые из них — просто заглушки.
Технические характеристики
Worklets ( спец .)
Worklets сами по себе не очень полезны. Это концепция, введенная для того, чтобы сделать возможными многие из более поздних проектов. Если вы подумали о Web Workers, когда прочитали «worklet», вы не ошиблись. У них много концептуальных совпадений. Так зачем что-то новое, когда у нас уже есть worker?
Цель Houdini — раскрыть новые API, чтобы позволить веб-разработчикам подключать свой собственный код к движку CSS и окружающим системам. Вероятно, не будет нереалистичным предположить, что некоторые из этих фрагментов кода придется запускать каждый. отдельный. кадр . Некоторые из них должны это делать по определению. Цитата из спецификации Web Worker :
Это означает, что веб-воркеры не подходят для того, что планирует делать Houdini. Поэтому были изобретены ворклеты. Ворклеты используют классы ES2015 для определения набора методов, сигнатуры которых предопределены типом ворклета. Они легкие и недолговечные.
CSS Paint API ( спецификация )
API Paint включен по умолчанию в Chrome 65. Прочитайте подробное введение .
Ворклет композитора
Описанный здесь API устарел. Рабочий лист Compositor был переработан и теперь предлагается как «рабочий лист Animation». Подробнее о текущей версии API читайте здесь.
Несмотря на то, что спецификация ворклета композитора была перемещена в WICG и будет итерирована, это одна из спецификаций, которая волнует меня больше всего. Некоторые операции передаются на аутсорсинг графической карте вашего компьютера движком CSS, хотя это зависит как от вашей графической карты, так и от вашего устройства в целом.
Браузер обычно берет дерево DOM и, основываясь на определенных критериях, решает дать некоторым ветвям и поддеревьям свой собственный слой. Эти поддеревья рисуют себя на нем (возможно, используя paint worklet в будущем). В качестве последнего шага все эти отдельные, теперь уже нарисованные, слои накладываются друг на друга и располагаются друг над другом, учитывая z-индексы, 3D-преобразования и т. д., чтобы получить окончательное изображение, которое отображается на экране. Этот процесс называется композицией и выполняется компоновщиком.
Преимущество процесса компоновки в том, что вам не нужно заставлять все элементы перерисовывать себя, когда страница немного прокручивается. Вместо этого вы можете повторно использовать слои из предыдущего кадра и просто перезапустить компоновщик с обновленной позицией прокрутки. Это ускоряет процесс. Это помогает нам достичь 60 кадров в секунду.

Как следует из названия, ворклет «Композитор» позволяет вам подключиться к компоновщику и повлиять на то, как слой элемента, который уже был нарисован, будет позиционироваться и накладываться поверх других слоев.
Чтобы быть немного более конкретным, вы можете сообщить браузеру, что вы хотите подключиться к процессу компоновки для определенного узла DOM и можете запросить доступ к определенным атрибутам, таким как позиция прокрутки, transform
или opacity
. Это принудительно помещает этот элемент в его собственный слой, и в каждом кадре ваш код будет вызываться. Вы можете перемещать свой слой, манипулируя преобразованием слоев и изменяя его атрибуты (например, opacity
), что позволяет вам делать причудливые вещи на колоссальных 60 кадрах в секунду.
Вот полная реализация параллакс-скроллинга с использованием ворклета Compositor.
// main.js
window.compositorWorklet.import('worklet.js')
.then(function() {
var animator = new CompositorAnimator('parallax');
animator.postMessage([
new CompositorProxy($('.scroller'), ['scrollTop']),
new CompositorProxy($('.parallax'), ['transform']),
]);
});
// worklet.js
registerCompositorAnimator('parallax', class {
tick(timestamp) {
var t = self.parallax.transform;
t.m42 = -0.1 * self.scroller.scrollTop;
self.parallax.transform = t;
}
onmessage(e) {
self.scroller = e.data[0];
self.parallax = e.data[1];
};
});
Роберт Флэк написал полифил для ворклета-композитора, так что вы можете его попробовать — очевидно, с гораздо более высоким влиянием на производительность.
Макет рабочего листа ( спецификация )
Предложен первый реальный проект спецификации. Реализация еще не скоро.
Опять же, спецификация для этого практически пуста, но концепция интригует: напишите свой собственный макет! Рабочий лист макета должен позволить вам сделать display: layout('myLayout')
и запустить ваш JavaScript для размещения дочерних элементов узла в поле узла.
Конечно, запуск полной реализации JavaScript для CSS flex-box
layout медленнее, чем запуск эквивалентной собственной реализации, но легко представить себе сценарий, в котором срезание углов может дать прирост производительности. Представьте себе веб-сайт, состоящий только из плиток, как Windows 10 или макет в стиле masonry. Абсолютное и фиксированное позиционирование не используется, как и z-index
, и элементы никогда не перекрываются и не имеют какой-либо границы или переполнения. Возможность пропускать все эти проверки при переразметке может дать прирост производительности.
registerLayout('random-layout', class {
static get inputProperties() {
return [];
}
static get childrenInputProperties() {
return [];
}
layout(children, constraintSpace, styleMap) {
const width = constraintSpace.width;
const height = constraintSpace.height;
for (let child of children) {
const x = Math.random()*width;
const y = Math.random()*height;
const constraintSubSpace = new ConstraintSpace();
constraintSubSpace.width = width-x;
constraintSubSpace.height = height-y;
const childFragment = child.doLayout(constraintSubSpace);
childFragment.x = x;
childFragment.y = y;
}
return {
minContent: 0,
maxContent: 0,
width: width,
height: height,
fragments: [],
unPositionedChildren: [],
breakToken: null
};
}
});
Типизированный CSSOM ( спецификация )
Типизированный CSSOM (CSS Object Model или Cascading Style Sheets Object Model) решает проблему, с которой мы, вероятно, все сталкивались и просто научились мириться. Позвольте мне проиллюстрировать это строкой JavaScript:
$('#someDiv').style.height = getRandomInt() + 'px';
Мы занимаемся математикой, преобразуя число в строку, чтобы присоединить единицу измерения, просто чтобы браузер проанализировал эту строку и преобразовал ее обратно в число для движка CSS. Это становится еще более уродливым, когда вы манипулируете преобразованиями с помощью JavaScript . Хватит! CSS скоро получит немного набора текста.
Этот проект является одним из наиболее зрелых, и работа над полифиллом уже ведется. (Отказ от ответственности: использование полифилла, очевидно, приведет к еще большему увеличению вычислительных затрат. Цель — показать, насколько удобен API.)
Вместо строк вы будете работать с StylePropertyMap
элемента, где каждый атрибут CSS имеет свой собственный ключ и соответствующий тип значения. Такие атрибуты, как width
имеют LengthValue
в качестве своего типа значения. LengthValue
— это словарь всех единиц CSS, таких как em
, rem
, px
, percent
и т. д. Установка height: calc(5px + 5%)
даст LengthValue{px: 5, percent: 5}
. Некоторые свойства, такие как box-sizing
просто принимают определенные ключевые слова и, следовательно, имеют тип значения KeywordValue
. Затем допустимость этих атрибутов может быть проверена во время выполнения.
<div style="width: 200px;" id="div1"></div>
<div style="width: 300px;" id="div2"></div>
<div id="div3"></div>
<div style="margin-left: calc(5em + 50%);" id="div4"></div>
var w1 = $('#div1').styleMap.get('width');
var w2 = $('#div2').styleMap.get('width');
$('#div3').styleMap.set('background-size',
[new SimpleLength(200, 'px'), w1.add(w2)])
$('#div4')).styleMap.get('margin-left')
// => {em: 5, percent: 50}
Свойства и ценности
( спецификация )
Знаете ли вы CSS Custom Properties (или их неофициальный псевдоним "CSS Variables")? Это они, но с типами! До сих пор переменные могли иметь только строковые значения и использовали простой подход поиска и замены. Этот проект позволит вам не только указать тип для ваших переменных, но и определить значение по умолчанию и повлиять на поведение наследования с помощью JavaScript API. Технически это также позволит анимировать пользовательские свойства с помощью стандартных переходов и анимаций CSS, что также рассматривается.
["--scale-x", "--scale-y"].forEach(function(name) {
document.registerProperty({
name: name,
syntax: "<number>",
inherits: false,
initialValue: "1"
});
});
Метрики шрифта
Метрики шрифта — это именно то, на что они похожи. Что такое ограничивающий прямоугольник (или ограничивающие прямоугольники), когда я рендерю строку X шрифтом Y размером Z? Что, если я использую аннотации Ruby ? Об этом много просили, и Houdini должен наконец-то воплотить эти пожелания в реальность.
Но подождите, это еще не все!
В списке черновиков Houdini есть еще больше спецификаций, но их будущее довольно неопределенно, и они не более чем заглушки для идей. Примерами служат пользовательские поведения переполнения, API расширения синтаксиса CSS, расширение поведения нативной прокрутки и подобные амбициозные вещи, все из которых позволяют делать на веб-платформе то, что раньше было невозможно.
Демо-версии
Я открыл исходный код для демо-версии ( живая демонстрация с использованием полифилла).