摘要:接下來我們將會更具體的說明是什麼東西和這傢伙會怎麼解決這些問題,並且列出目前開發(fā)中一些令人興奮的功能。這個功能甚至還沒有一個瀏覽器支援。完整的清單請查閱目前還未被寫入規(guī)範,意思是這邊提到任何內(nèi)容極有可能會改變。
譯者:其實...我想說這可能是最令我感到興奮..但又害怕頭痛的功能... 附上原文連結(jié)
你曾經(jīng)想要使用某個 CSS 的新功能,但是最後卻因為這個功能瀏覽器還未全面支援而放棄了嗎?甚至更糟糕的狀況,瀏覽器已經(jīng)支援了但卻充滿問題。我敢打賭這些情況你肯定遇過了。如果上面這種情形你曾經(jīng)遇過,那麼你是應(yīng)該關(guān)心一下 Houdini。
Houdini 是 w3c 新的任務(wù)團隊,他們的終極目標就是解決上面這些問題 - 讓瀏覽器更迅速廣泛的支援 CSS 新特性。這個計畫試圖透過提供一系列新的 API,也是第一次讓開發(fā)者可以擴充 CSS 本身的能力。透過 hook 的方式讓我們可以在瀏覽器渲染的過程動點手腳。
Hooks 簡易說明:Hooks 英文翻譯為鉤子,在程式術(shù)語中所表達的是在程式特定位置埋入一段預(yù)留的程式碼,用來呼叫其他對應(yīng)的程式碼??梢源舐韵氤稍谀硞€片段先空出一個位置,這個位置可以在事後再放入動作,不放也沒關(guān)係。
不過具體來說這到底是什麼意思?這麼做真的好嗎?還有這樣做到底能在我們的開發(fā)過程提供些什麼幫助。
在這篇文章,我將試著回答這些問題。不過在這之前我們必須要先搞清楚,到底我們在今時今日遇到什麼問題,為什麼我們需要做這些改變。接下來我們將會更具體的說明 Houdini 是什麼東西和這傢伙會怎麼解決這些問題,並且列出目前開發(fā)中一些令人興奮的功能。最後我將提供一些比較具體實例的說明。
Houdini 試圖要解決什麼問題?每一次當(dāng)我寫了一篇文章來介紹一些 CSS 的新功能時總是會有人留言像是 這實在太棒了! 不過我們可能要再等個 10 年才能使用 我能體會這種毫無建設(shè)性的留言....從過往的歷史來看,這的確需要花上好幾年的時間從功能提案到廣泛採用。而其中最關(guān)鍵的原因是唯一讓 CSS 增加新功能的方式就是透過下面這個標準流程。
因為瀏覽器本身牽涉太廣泛,對於這樣的流程我本身沒有任何反對意見。當(dāng)然我們也知道這會耗掉很長的時間。舉例來說 flexbox 首次提案是在 2009 年,而時至今日我們還是見到開發(fā)者在抱怨支援的瀏覽器不夠。這個問題正緩慢的解決中,因為幾乎所有的瀏覽器都會自動更新,不過即使是現(xiàn)代瀏覽器(Modern Browser)在功能提案到實際能使用該功能還是有一段挺長的時間。
有趣的是並不是所有 Web 領(lǐng)域的東西都處在這樣的情況,看看最近的 Javascript,為什麼 Javascript 可以發(fā)展如此迅速
從上圖這種流程,構(gòu)想提案到實際用在產(chǎn)品上有時候只需要幾天的時間。例如:我已經(jīng)在產(chǎn)品上使用了 async/await 的功能。這個功能甚至還沒有一個瀏覽器支援。
你還可以看到兩個社群截然不同的狀況,在 Javascript 社群你可以聽到人們開始在抱怨更新速度太快,而在 CSS 社群則多是看到一堆人在抱怨學(xué)那麼多東西沒用,還需要非常久的時間才能使用。
那為什麼我們不可以使用 CSS Polyfills?看完 Javascript 的流程第一個直覺的想法是那我們也來為 CSS 提供 Polyfills,聽起來可能蠻可行的,如果有 Polyfills 那麼 CSS 也可以像 Javascript 一樣快速的演進,不是嗎?可惜的是,這並不像想的那麼容易,用舊有技術(shù)實現(xiàn)新的功能或 API 在 CSS 中異常的困難,在大部分的情況下會整個犧牲掉效能。
Javascript 是一個動態(tài)語言,意味著我們相對容易用 Javascript 替 Javascript 補上 Polyfills。對 CSS 來說我們相對很少使用 CSS 來做 Polyfills。一般頂多就是使用轉(zhuǎn)譯器來產(chǎn)生 CSS 例如 PostCSS 就是這樣的東西。
如果你想直接對 DOM 結(jié)構(gòu)或者元素的 Layout,位置加上 Polyfills,那麼我們就必須要在客戶端執(zhí)行對應(yīng)的邏輯程式。
不幸的是瀏覽器對於這方面並不提供任何簡單的方式。
下圖我們簡單的歸納瀏覽器從收到 HTML 文件到顯示在螢?zāi)簧细怕缘牧鞒?。藍色區(qū)塊就是 Javascript 能夠控制結(jié)果的關(guān)鍵點
在上圖中我們認知到身為一個開發(fā)者,你對於瀏覽器解析 HTML 和 CSS 轉(zhuǎn)換成 DOM, CSSOM 的過程幾乎沒有控制權(quán),尤其在瀏覽器對元素佈局以及渲染方面。唯一在這個過程中我們能夠掌握的就是 DOM 的存取,是不是該換 CSSOM 做些開放了。不過這邊先提一下 Houdini 網(wǎng)站上提到的改良 CSSOM的部分:確認跨瀏覽器行為不一致以及缺少關(guān)鍵功能的問題。
關(guān)於缺少關(guān)鍵功能部分,舉例來說,瀏覽器中的 CSSOM 並不會顯示跨站存取的樣式規(guī)則,而且會直接忽略那些它看不懂的樣式,這也意味著如果你想增加一個瀏覽器未支援的功能,你是不可以使用 CSSOM。反而要用 DOM 去找到 和 自己取得 CSS 然後解析再把它們補回 DOM。當(dāng)然,更新 DOM 通常也表示瀏覽器必須要重新執(zhí)行整個流程。
雖然整個流程重新渲染看起來並不會造成非常嚴重的效能問題,甚至這可能已經(jīng)是常出現(xiàn)的情況,不過如果我們需要處理像是 scoll window resize mouse keyboard 這些事件,大量的更新次數(shù)可能就會很明顯地看出變慢了。更慘的是當(dāng)你發(fā)現(xiàn)大部分的 CSS Polyfills 都有它們自己的解析方式和套用邏輯,而解析和套用是非常複雜的事情,導(dǎo)致這些 polyfills 通常不是很肥就是容易出錯。
總結(jié)上述所說的就是,現(xiàn)階段如果你想要瀏覽器對於呈現(xiàn)做些不同的行為那麼你就必須要靠 DOM 去調(diào)整。
但,為什麼我需要修改瀏覽器內(nèi)部的渲染引擎?對我來說,這絕對是能夠回答整篇文章最關(guān)鍵的問題。如果你已經(jīng)看到這邊,請仔細的閱讀這個部分!
看到這邊我很肯定有一部份的人會想:我根本不需要這個。我只是建置一個一般的網(wǎng)頁,我不會想去對瀏覽器內(nèi)部動手腳。如果你是這麼想的,那麼我強烈建議你先停一下,去檢查過去你已經(jīng)用在開發(fā)中的那些技術(shù)。對瀏覽器套用樣式的流程取得一些存取權(quán)限和 hooks 並不是只為了創(chuàng)造一些很屌的火力展示 - 這主要是希望給開發(fā)者和框架作者有更多的解決方案,功能去完成下面這兩件事:
統(tǒng)一跨瀏覽器樣式的不同行為
開發(fā)新功能或者解決相容性問題 - 補上新功能的 polyfills ,讓我們可以快點使用到這些新技術(shù)
如果你曾使用過像是 jQuery 這類的函式庫,你已經(jīng)受惠於這種功能!事實上,這也是現(xiàn)今大多數(shù)前端框架或函式庫的主要賣點。Github 上 5 個流行的 Javascript 專案 - AngularJS, D3, jQuery, React, Ember 都處理了很多跨瀏覽器不同行為的問題。
不過上面說的是 Javascript 的部分,現(xiàn)在讓我們來想想關(guān)於 CSS 和所有跨瀏覽器的問題。即便是最流行的 CSS Framework 像 Bootstrap,F(xiàn)undation 也聲明跨瀏覽器相容性的問題他們並沒有完全處理 - 只是避開那些問題??鐬g覽器 CSS 的 bug 不只在過去存在,即使是今天也還存在像是 flexbox` 的問題。
想像一下如果任何 CSS 的樣式規(guī)則可以確保在任何瀏覽器有著一致的行為那我們的開發(fā)生涯該是多麼美好。再進一步如果任何你從 Blog,Conferences 或 Meetup 得知的新功能像是 CSS Grids, CSS Sanp points, Sticky positioning 我們馬上就能夠在今天開始使用,而你需要做的就是從 Github 下載程式碼。
這就是 Houdini 的理想。這個未來正是該工作團隊試圖實現(xiàn)的目標。你說你根本不想去撰寫那些 polyfills 也沒關(guān)係,但你大概會想使用吧???畢竟只要有人寫出 polyfills 我們就可以從中得到幫助。
那麼 Houdini 現(xiàn)階段有什麼功能正在開發(fā)?如同上面提到的,開發(fā)者對於瀏覽器渲染的過程沒有太多存取控制的機會,現(xiàn)階段只能從 DOM 下手。
為了解決這個問題,Houdini 團隊將提倡了一些新的規(guī)範,關(guān)於在渲染流程中賦予開發(fā)者其他部分的控制權(quán)。下圖顯示新的規(guī)範中開發(fā)者可以操作的部分。注意規(guī)範中灰色區(qū)塊是已規(guī)劃但還未被寫入規(guī)範的。
下面我們將簡介每個新的規(guī)範並且說明其功能。完整的清單請查閱Houdini Drafts
CSS Parser APICSS Parser API 目前還未被寫入規(guī)範,意思是這邊提到任何內(nèi)容極有可能會改變。不過基本來說它的概念是讓開發(fā)者可以擴充 CSS Parser ,提供新的語法結(jié)構(gòu),舉例來說:新的 media 語法,新的偽類 pseudo-classes 等等
一旦解析器知道關(guān)於新的結(jié)構(gòu),它就可以正確地將其運用在 CSSOM 上。
CSS 屬性與值的 APICSS 已經(jīng)具有客製屬性的功能,並且在之前的文章說明過對此感到非常興奮。CSS 屬性與值的 API除了自訂屬性將更進一步使其具備型別。
關(guān)於加入型別有非常多的好處,不過大體來說最大的賣點就是讓開發(fā)者可以客製 transition 和 animate。這在今天是辦不到的。不懂???看看下面的例子
body { --primary-theme-color: tomato; transition: --primary-theme-color 1s ease-in-out; } body.night-theme { --primary-theme-color: darkred; }
上面的例子如果 night-theme class 被加到 元素那麼該頁面有參考 --primary-theme-color 屬性的值將會慢慢的從 tomato 轉(zhuǎn)換到 darkred。如下範例
p { color: var(--primary-theme-color); }
在現(xiàn)階段,如果你要完成這個功能你得為每一個元素撰寫 transition,因為現(xiàn)在過渡效果是跟在元素上並不是跟著屬性。另一個有趣的功能就是註冊 hook,提供開發(fā)者一個方式來修改自訂屬性的最終值,用在 polyfills 方面這可能是非常實用的。
CSS Typed OMCSS Typed OM大概就是目前 CSSOM 第二版的概念。目的是解決當(dāng)前 CSS 模型的問題,也包含 CSS Parser API 和 CSS 屬性和值 API 追加的新功能。
Typed OM 另外一個主要的目標是改善效能。將 CSSOM 目前使用的字串值換成具意義型別,因此在Javascript 操作的表現(xiàn)會得到顯著效能的提升。
CSS Layout APICSS Layout API提供開發(fā)者撰寫自己的佈局模組。透過佈局模組意味著任何東西可以被傳入 display 屬性。這將是第一次開發(fā)者有辦法透過原生的方式改變佈局提供像是 display: flex 和 display: table 這樣不同的模組。
例如 Masonry Layout 流瀑式版型 這樣複雜的佈局方式在今天是不可能單單只透過 CSS 就完成的。雖然它的效果令人驚艷但可惜的是通常都有效能相關(guān)的問題,在低階的裝置上尤其明顯。
CSS Layout API 讓開發(fā)者透過 registerLayout 的方法,允許註冊一個 layout 的名稱,然後用一個 Javascript class 來組織邏輯。下面就是一個簡單的範例
registerLayout("masonry", class { static get inputProperties() { return ["width", "height"] } static get childrenInputProperties() { return ["x", "y", "position"] } layout(children, constraintSpace, styleMap, breakToken) { // Layout logic goes here. } }
如果你感受不到上面範例的意義,也不用擔(dān)心。最主要的是說你可以像下面範例這樣使用,你只要找到別人寫好的例如 masonry.js 接著在 CSS 中使用就好了。
body { display: layout("masonry"); }CSS Paint API
CSS Paint API 和 Layout API 非常類似,不過它提供一個 registerPaint 方法。開發(fā)者可以在 CSS 中使用 paint() 函式,透過傳入的名稱產(chǎn)生一個 CSS 圖片。這邊有個簡單的範例就是繪製一個有顏色的圓形
registerPaint("circle", class { static get inputProperties() { return ["--circle-color"]; } paint(ctx, geom, properties) { // Change the fill color. const color = properties.get("--circle-color"); ctx.fillStyle = color; // Determine the center point and radius. const x = geom.width / 2; const y = geom.height / 2; const radius = Math.min(x, y); // Draw the circle o/ ctx.beginPath(); ctx.arc(x, y, radius, 0, 2 * Math.PI, false); ctx.fill(); } });
CSS 的用法如下
.bubble { --circle-color: blue; background-image: paint("circle"); }
現(xiàn)在套用 .bubble 的元素會產(chǎn)生一個藍色圓形的背景圖。這個圓會跟元素尺寸一樣且置中。
Worklets關(guān)於上面列出的規(guī)範和一些範例你可能會想知道你該把它們放在哪裏?答案是 worklet scripts。worklets 類似於 Web workers,它允許我們匯入 script 檔案,可以在不同的階段執(zhí)行 Javascript 程式碼,並且它不相依於主要執(zhí)行緒。worklet script 為了確保效能會嚴格的限制能夠操作的型別。
捲軸效果和動畫雖然針對捲軸效果(scrolling)和動畫方面還沒有官方的規(guī)範,不過這是 Houdini 其中一個備受期待的功能。最終 API 會允許開發(fā)者將程式邏輯放在一個負責(zé)組織執(zhí)行的 worklet,而不是主要執(zhí)行緒上。這個東西會支援修改一些 DOM 的屬性。透過這種方式就可以只更新特定屬性,而不是全部重新渲染。
如此一來開發(fā)者就可以容易的做出高效能的 scrolling 和動畫類型的應(yīng)用,例如 sticky scroll header 或是平行捲動 parallax 的效果。你可以在使用案例中得知這些 API 試圖要解決的問題。
儘管還沒有正式的官方規(guī)範,實驗性的開發(fā)已經(jīng)在 Chrome 上展開了。事實上 Chrome 團隊目前正在使用這些主要的 API 實作 CSS Snap point 和 Sticky positioning。這是很驚人的,因為這意味著 Houdini API 有足夠的效能讓 Chrome 新功能採用。
如果你仍然擔(dān)心 Houdini 效能的問題,你可以看看下面這個影片以及原始碼
如同上面提到的,我想每一個網(wǎng)站開發(fā)者都應(yīng)該關(guān)注 Houdini。這將是讓我們開發(fā)生活變得更美好的未來。即使你不會直接使用 Houdini 規(guī)範內(nèi)定義的東西,你幾乎會用到架構(gòu)在它之上的許多東西。雖然這個未來還不會立即到來,但它可能比我們想的還要快到來。
所有主流瀏覽器的廠商在 2016 年初已經(jīng)在雪梨有場面對面的會議交流,對於 Houdini 的建置與開發(fā)沒有太多異議??梢哉f Houdini 是否會成為下一件大事已經(jīng)不是個問題,問題應(yīng)該是何時導(dǎo)入比較恰當(dāng)。
當(dāng)然瀏覽器供應(yīng)商對於建置這些新功能自有一些優(yōu)先順序,通常會根據(jù)那些使用者迫切需要的功能為優(yōu)先。所以如果你關(guān)心這個關(guān)於樣式與佈局的擴展功能,你希望可以不用等待瀏覽器開發(fā)商經(jīng)過漫長的開發(fā)程序,就使用 CSS 的新功能請告訴那些相關(guān)的開發(fā)成員你需要這個功能。
另一方面你可以透過提供一些真實世界的使用案例,就是那些你想做的功能但現(xiàn)今技術(shù)卻異常難實現(xiàn)。已經(jīng)有一些案例列在這個 Github 專案。你可以透過發(fā)個 Pull Request 來加入?yún)f(xié)作。
Houdini 開發(fā)團隊真的希望能夠從網(wǎng)頁開發(fā)人員中取得真正需求與問題,使這些功能更加完善周到。因為通常參與規(guī)格書制訂的工程師只專注在瀏覽器身上,他們並不知道應(yīng)用程式開發(fā)者的痛點。全靠我們來告訴他們了。
參考資源CSS-TAG Houdini Editor Drafts - W3C 最新草稿
CSS-TAG Houdini Task Force Specifications - 官方 Github 專案
Houdini Samples - 實驗範例
原文出處
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/115140.html
摘要:載入流程被限制在兩個階段根據(jù)上面的模式,內(nèi)嵌透過隱藏尚未套用樣式的內(nèi)容,然後非同步得載入之後呈現(xiàn)內(nèi)容。樣式表本身的載入機制是平行的,但是套用樣式卻是要照順序的。我們需要一點小技巧來避免。 這週閱讀到這篇有意思的文章,於是便動手寫下簡單的翻譯,如果有理解錯誤的地方歡迎指教。 Chrome 正在試圖改變當(dāng) 寫在 的行為,從blink-dev 的文章並不能很清楚的知道其優(yōu)點。所以這篇文章...
摘要:整體來說網(wǎng)頁主要是由矩形所構(gòu)成的,另一方面印刷品則具備相對多樣性。即便我們設(shè)定的元素不再是矩形,但周圍的元素排列方式仍然維持原本矩形的佈局。為了達成周圍的元素跟著裁切的形狀,我們可以使用屬性。周圍的元素仍需要靠來修正。 整體來說網(wǎng)頁主要是由矩形所構(gòu)成的,另一方面印刷品則具備相對多樣性。造成這樣差異的原因有很多,不過其中一個即是缺少合適的工具。 這篇文章主要會介紹 clip-path 這...
摘要:不過到底是怎麼保留的另外為什麼一個閉包可以一直使用區(qū)域變數(shù),即便這些變數(shù)在該內(nèi)已經(jīng)不存在了為了解開閉包的神秘面紗,我們將要假裝沒有閉包這東西而且也不能夠用嵌套來重新實作閉包。 原文出處: 連結(jié) 話說網(wǎng)路上有很多文章在探討閉包(Closures)時大多都是簡單的帶過。大多的都將閉包的定義濃縮成一句簡單的解釋,那就是一個閉包是一個函數(shù)能夠保留其建立時的執(zhí)行環(huán)境。不過到底是怎麼保留的? 另外...
摘要:中的執(zhí)行環(huán)境與堆疊在這篇筆記中我將會深入的探討底層中的一些觀念,其中最重要的就是執(zhí)行環(huán)境。其他執(zhí)行環(huán)境都可以存取全域的東西。在這個階段直譯器會建立,透過掃描函式傳入的參數(shù),內(nèi)部的函式宣告,變數(shù)宣告。 Javascript 中的執(zhí)行環(huán)境與堆疊 在這篇筆記中我將會深入的探討 JS 底層中的一些觀念,其中最重要的就是執(zhí)行環(huán)境(Execution Context)。當(dāng)您閱讀完這篇文章後您可能會...
摘要:不過這個效果感覺上就像是閃一下就切換到該位置。為了使用體驗上的感覺有時候網(wǎng)站會設(shè)計一種平滑捲動到該位置的效果。的方式非常簡單,只要在該元素設(shè)定注意是而不是這個方式非常方便不過目前只有支援,查閱。 眾所皆知 HTML 錨點(anchor link)透過給定標籤 id 屬性跳到頁面上特定位置的功能。不過這個效果感覺上就像是閃一下就切換到該位置。為了使用體驗上的感覺有時候網(wǎng)站會設(shè)計一種平滑捲...
閱讀 3651·2023-04-26 02:10
閱讀 1466·2021-11-22 15:25
閱讀 1732·2021-09-22 10:02
閱讀 982·2021-09-06 15:02
閱讀 3537·2019-08-30 15:55
閱讀 663·2019-08-30 13:58
閱讀 2837·2019-08-30 12:53
閱讀 3124·2019-08-29 12:38