Houdini - 揭開 CSS 的神秘面紗

您是否曾思考 CSS 供應商的工作量?變更單項 屬性,導致整個網站都以不同的版面配置方式顯示。是 magic 搭配。到目前為止,我們 (網頁程式開發人員社群) 擁有 也能夠見證和觀察神奇的魔力我們可以 我們自己的魔法呢?如果我們想成為魔術師,該怎麼做?

進入 Houdini!

Houdini 任務小組是由 Mozilla、Apple、Opera、 Microsoft、HP、Intel 和 Google 攜手合作,公開 導入網頁程式開發人員的 CSS 引擎任務團隊目前負責打造 草稿,目標是在 W3C 獲準後成為實際網頁 標準。他們為自己設定了幾個概略目標,並轉換成 它們依序提供一組支援 適用於較低層級的規格草稿

這些草稿的收集方式通常是在觀眾討論話題時 「Houdini」撰寫時,草稿清單是 部分草稿不完整,部分草稿只是預留位置。

規格

小程式 (spec)

工作程式本身沒那麼實用。這個概念 盡量使用許多較晚的草稿如果您將 讀取「worklet」,而且完全不答對。他們的概念很重疊為什麼要 會有什麼新東西呢?

Houdini 的目標是公開新的 API 可讓網頁程式開發人員將自己的程式碼匯入 CSS 引擎, 周遭的系統假設你使用了上述某些功能,可能並非不切實際 片段就必須執行每次單曲。影格。但有些必須 物件引用 Web Worker 規格

這表示 Web Worker 無法因應 Houdini 的計畫。 因此,我們發明瞭 Worklet。小程式利用 ES2015 類別來定義 方法集合,這些簽章的簽章是由 工作小程式的類型它是輕量、短時間。

CSS Paint API (規格)

根據預設,Chrome 65 會啟用 Paint API。閱讀 詳細介紹

合成器小程式

此處描述的 API 已過時。合成器工作程式有 設計成「Animation Worklet」詳情請造訪 API 目前的疊代

雖然合成程式規格已移至 WICG 但會反覆出現,這是最激起我興趣的一種規格。只有部分通知 這些作業會由 CSS 外包給電腦的顯示卡 但這必須同時運用您的顯示卡和 通則。

瀏覽器通常會採用 DOM 樹狀結構,並按照特定條件 因此決定為部分樹枝和子樹狀結構賦予自己的層次 這些子樹會自畫上一面 (可能在 。最後,所有這些人員 (現在已經過繪製) 並放置在彼此上方,依循 Z 索引、3D 轉換和 以產生畫面上顯示的最終圖像。這項程序 稱為「撰寫」,是由合成器執行。

合成程序的好處是您不必完全 當頁面捲動稍微時,元素就會自行繪製。而是 就可以重複使用上一個影格中的圖層,然後使用 更新的捲動位置這可以加快處理速度。這個做法會達到 60fps。

合成器小程式。

顧名思義,合成器工作程式可讓您掛入合成器 並影響元素圖層的繪製方式 疊加在其他圖層上

只要 即可告訴瀏覽器您希望納入合成文字 特定 DOM 節點的程序,並能要求存取某些屬性,例如 捲動位置,transformopacity。這會強制此元素在 且每個影格都會呼叫程式碼你可以移動圖層 藉由操控圖層轉換並變更其屬性 (例如 opacity) 讓你以 60 fps 呈現精緻的細節。

以下是使用合成器進行視差捲動的完整實作內容 Worklet。

// 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 已針對 polyfill 不妨試試這項功能,當然還有許多 效能對效能的影響。

版面配置小程式 (規格)

已提議第一個真實規格草稿。實作 你出門也會好

再次提醒,這個作業的規格幾乎沒有任何內容 引人入勝:撰寫自己的版面配置!版面配置工作程式應可讓您 執行 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 (規格)

輸入的 CSSOM (CSS 物件模型或階層式樣式試算表物件模型) 可解決 畢竟我們都曾遇到過,才剛學到如何補足問題。 讓我們說明一行 JavaScript:

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

我們要做數學題,將數字轉換為字串 來附加一個單位 瀏覽器剖析該字串,並轉換回 CSS 引擎的數字。 使用 JavaScript 操控轉換時,這種做法會更難處理。 不要再來了!CSS 即將輸入文字

這個草稿是較成熟的草稿之一,polyfill 則是 處理的工作(免責事項:使用 polyfill 基本上可以 導致更多運算負擔重點是展示 API 是)。

您必須處理元素的 StylePropertyMap 而非字串,其中 每個 CSS 屬性都有專屬的鍵和對應值類型屬性 例如 width 的值類型為 LengthValueLengthValue 是一種 所有 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}

屬性和值

(規格)

您是否知道 CSS 自訂屬性 (或非官方別名「CSS 變數」) 嗎? 這些只是類型而已!目前為止,變數只能包含字串值 我們採用的是簡單的搜尋與取代方法製作這份草稿 為您的變數指定類型,但同時定義預設值和 影響繼承行為技術上,這個 也允許自訂屬性透過標準 CSS 轉換動畫 而且這些素材資源也會納入考量

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

字型指標

字型指標就是其聽起來的內容。定界框為何? 定界框) 時,如何使用 ruby 註解?許多人都曾要求我們這麼做 願你能實現這些願望。

等一下,好處可不只這些!

Houdini 的草稿清單還有更多規格 而且不會只是提案的預留位置 例如自訂溢位行為、CSS 語法擴充功能 API、擴充功能 表現出原生捲動行為的種種偏見 網路平台帶來前所未有的功能

示範

我已將示範程式碼的開放原始碼 (使用 polyfill 的即時示範)。