Houdini - CSS に関する誤解の解消

CSS の作業量について考えたことはありますか?1 つの 属性を使用すると、ウェブサイト全体が突然別のレイアウトで表示されます。です。 まるで魔法のようなものです。ウェブ デベロッパーのコミュニティには、これまでに 魔法を目撃したり観察したりすることができなかったのです。では、ルールを どうすればよいでしょうか。マジシャンになりたいとしたら?

Houdini に登場!

Houdini のタスクフォースは、Mozilla、Apple、Opera、 Microsoft、HP、Intel、Google が連携して ウェブ デベロッパーに提供します作業部会は、 ドラフトを作成し、W3C に承認されて実際のウェブとなるようにする 対応できます。同社はいくつかのハイレベルな目標を設定し、 これがサポート、対応、復旧という一連の 下位レベルの仕様のドラフトを作成できます

これらのドラフトのコレクションは、 「Houdini」。このドキュメントの作成時点では、回答案のリストは次のとおりです。 下書きの一部は単なるプレースホルダです

仕様

ワークレット(仕様

ワークレットだけではあまり役に立ちません。これらは Google Cloud で 以降のドラフト版も 活かせるようにしていますウェブワーカーを念頭に置いて 「ワークレット」を読むとしたら、間違いではありません。コンセプトは重複する部分が多くあります。では、なぜ どうすればよいでしょうか。

Houdini の目標は、新しい API を公開すること ウェブ デベロッパーが独自のコードを CSS エンジンと サポートしています。その一部であると仮定しても、おそらく非現実的ではないでしょう。 コード フラグメントは、あります。フレーム。中には、 なります。ウェブワーカーの仕様の引用:

<ph type="x-smartling-placeholder">

つまり、Web ワーカーは Houdini の計画には対応できません。 そのため、ワークレットが考案されました。ワークレットは ES2015 クラスを利用して、 メソッドの集合であり、そのシグネチャは ワークレットのタイプ。軽量で短命です。

CSS Paint API(仕様

Chrome 65 では、Paint API がデフォルトで有効になっています。詳しくは、 こちらをご覧ください。

コンポジタ ワークレット

ここで説明する API は古いものです。コンポジタ ワークレット 再設計され、「アニメーション ワークレット」として提案されるようになりました。詳しくは、 現在のイテレーションの API

コンポジタ ワークレットの仕様は WICG に移行していますが、 この仕様を最も興味を引かれる点です。一部 作業は CSS によってコンピュータのグラフィック カードにアウトソーシングされている ただし、グラフィック カードとデバイスの両方によって あります。

通常、ブラウザは DOM ツリーを取得し、特定の基準に基づいて 次に、一部のブランチとサブツリーに独自のレイヤを付与することにしました。 これらのサブツリーは自身をペイントします( 導入します。最後に、これらのペイントされた個々のレイヤを積み重ねます。 Z インデックス、3D 変換、 画面上に表示される最終的な画像が生成されます。このプロセスは コンポジットと呼ばれ、コンポジタによって実行されます。

合成プロセスの利点は、すべての要素を ページが少しスクロールすると、要素が再描画されます。代わりに、 前のフレームのレイヤを再利用して、 更新します。処理が速くなります。これにより 60 fps を達成できます。

コンポジタ ワークレット。

名前が示すように、コンポジタ ワークレットを使用すると、コンポジタに接続できます。 すでにペイントされている要素のレイヤが、どのように 他のレイヤの上に重ねて配置されます

その他の 具体的には、合成したいデータをブラウザに 処理し、次のような特定の属性へのアクセスをリクエストできる スクロール位置(transform または opacity)。これにより、この要素が 各フレームでコードが呼び出されます。レイヤは移動できます。 レイヤ変換を操作してその属性(opacity など)を変更する 60 fps という驚くべき高速処理を実現します。

コンポジタを使用した視差スクロールの完全な実装は次のとおりです。 ワークレットです

// 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];
    };
});

Robert Flack は、 試してみましょう。 パフォーマンスへの影響が大きくなります

レイアウト ワークレット(spec

最初の実際の仕様ドラフトが提案されました。実装 しばらく遠いよ。

ここでも仕様は実質的に空ですが、コンセプトは 興味をそそります。独自のレイアウトを記述してください。レイアウト ワークレットは、 display: layout('myLayout') を実行し、JavaScript を実行してノードの ノードのボックス内に子を追加します。

もちろん、CSS の flex-box レイアウトの完全な JavaScript 実装を実行します。 同等のネイティブ実装を実行する場合よりも時間がかかりますが、 コーナーをカットすることでパフォーマンスが向上するシナリオを想像してみてください。たとえば Windows 10 やコンクリート形式のタイルなど、タイルだけで構成されているウェブサイト できます。絶対位置と固定位置は使用しません。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(仕様

<ph type="x-smartling-placeholder">

型付き CSSOM(CSS オブジェクト モデルまたはカスケーディング スタイル シート オブジェクト モデル)は、 おそらく誰もが直面し、つい最近知った問題です。 JavaScript の例で説明します。

    $('#someDiv').style.height = getRandomInt() + 'px';

計算を行っています。数値を文字列に変換し、単に単位を付加します。 ブラウザはその文字列を解析し、CSS エンジン用の数値に変換します。 これは、JavaScript で変換を操作するとさらに困難になります。 いやだ!CSS が入力しようとしています。

このドラフトはより成熟したドラフトの 1 つで、ポリフィルは 進めていきます(免責条項: ポリフィルを使用すると、 計算オーバーヘッドがさらに増加します。ポイントは、データがいかに便利かを示すことです。 API などです)。

文字列ではなく、要素の StylePropertyMap で作業します。ここで、 各 CSS 属性には、独自のキーと対応する値の型があります。属性 width などでは、値の型として LengthValue があります。LengthValueとは すべての CSS ユニットの辞書(emrempxpercent など)の辞書を返します。設定 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}

プロパティと値

spec

CSS カスタム プロパティ(または非公式のエイリアス「CSS 変数」)をご存じですか? 型があるだけだ。これまでのところ、変数には文字列値と 単純な検索と置換のアプローチを採用していました。この下書きでは、次のことは行えません。 変数の型のみを指定するだけでなく、デフォルト値と 継承動作を制御するには、JavaScript API を使用します。これは厳密に言えば、 標準の CSS 遷移でカスタム プロパティをアニメーション化することもできます。 3 種類あります

["--scale-x", "--scale-y"].forEach(function(name) {
document.registerProperty({
    name: name,
    syntax: "<number>",
    inherits: false,
    initialValue: "1"
    });
});

フォントの指標

フォントの指標はその名のとおりです。境界ボックス( 境界ボックスなど)が表示されるのはなぜですか?Cloud Shell を使用して、 ruby アノテーション多くの要望が寄せられており、Houdini が最終的に 願いをかなえてくれます。

他にもあります。

Houdini のドラフトリストにはさらに多くの仕様がありますが、将来的には むしろ不確実で、アイデアの代弁に過ぎません。 例: カスタムのオーバーフロー動作、CSS 構文拡張 API、拡張機能 ネイティブのスクロール動作と同様に 意欲的なものを提供できるため 新しいことが可能になりました。

デモ

このデモのコードをオープンソース化しました (ポリフィルを使用したライブデモ)。