你是否曾经试过想使用某个CSS特性可是却由于他没有被全部浏览器支持而不能用?又或者更糟糕的,他被所有浏览器支持,可是这种支持充满了bug、表现不一致甚至是不彻底兼容的?若是这些事情曾经在你身上发生过——而且我打赌他们绝对发生过——那么你就须要关注一下。
Houdini是一个新的W3C工做组,他们致力于让这些问题永远消失。他们计划经过引入一整套API来让开发者首次拥有扩展CSS的权利,而且会提供出一套工具来与浏览器的渲染引擎的样式与布局进行挂钩。
可是这意味着什么呢?这是一个好的提议吗?这会如何帮助咱们开发者在现今与将来构建网页呢?
在这篇文章里,我将尝试去回答这些问题。可是在我回答以前,弄清楚今天咱们遇到了什么问题和为何须要这样的变革是很重要的。而后我会更详尽地去解释Houdini如何去解决这些问题,而且列出一些在现今开发上十分使人振奋的特征。最后,我会提供一些具体的,咱们的开发者如今能够去完成的事情来让Houdini变成现实。
Houdini尝试解决什么问题呢
每次我为一些全新的CSS特征编写文章或者构建一个demo,必然会有人在评论或者推特上说,“这真的很棒!不过咱们可能将来十年都不会用到它们。”
像这些烦人且毫无建设性的评论,我能够理解那种情绪。从历史上来看,一个功能建议要花费数年才能被普遍使用。其缘由在于,纵观整个web的历史,惟一能让一个新特征加入CSS的方法就是走完整个标准过程。
固然我不是反对标准过程,可是不能否认的是他花费太多时间了。
例如,[url=]flexbox[/url]在2009年第一次被提出,然而直至今天,开发者仍然抱怨由于缺少浏览器的支持而不能使用它。固然,这个问题正在慢慢的被解决由于如今几乎全部现代浏览器都会自动更新;可是即便是现代浏览器,从功能提议到全面上市仍然会有延迟。
有趣的是,并非全部web的领域都是这样。看一下在JavaScript上事情最近是怎么发生的:
在这种状况下,可能只须要花费几天就能把一个想法运用到生产中去。个人意思是,我已经在生产中使用async/await了,可是这个功能仍然未被加入到任何一个浏览器中。
你还能够看到这两个社区的广泛情绪上的巨大差别。在JavaScript社区,你会阅读到人们抱怨变化太快的文章。而在CSS社区,相反你听到的是人们哀叹学习新东西的徒劳由于他们不知道何时才能使用他们。
因此为何咱们不编写更多的CSSPolyfills呢?
第一个想法就是,编写更多CSSpolyfills彷佛是解决问题的方法。若是有了良好的polyfills,CSS就能够像JavaScript那样快速前进了,不是吗?
而后悲伤的是,并无那么简单。对CSS进行polyfill是难以置信的困难,大部分状况下,你不能在彻底不破坏性能的状况下去完成polyfill。
JavaScript是一个动态语言,这意味着你可使用JavaScript来polyfill JavaScript。又由于他是动态的,因此他特别容易被拓展。反之,CSS很难被用来polyfill CSS。某些状况下,你能够在编译步骤里面转化编译CSS([url=]PostCSS[/url]负责这种工做);可是若是你想polyfill任何基于DOM结构的或者是元素布局位置的属性,你必需要在客户端运行你的polyfill逻辑。
不幸的是,在浏览器上完成这项任务并不容易。
下图勾勒出了你的浏览器如何把一个HTML文件展示到屏幕上的过程。用蓝色标注的部分是JavaScript有权利控制的部分:
图片显示的结果至关惨淡。做为一个开发者,你并不能控制你的浏览器如何解析HTML和CSS也不能控制他如何把HTML和CSS转化成[url=]DOM[/url]和[url=]CSS对象模型[/url](CSSOM)。你没法控制级联。你没法掌控浏览器如何在DOM里布局元素,如何在屏幕上绘制元素。你也没法控制合成器。
惟一一个你能够所有控制的进程就是DOM。CSSOM部分开放;然而,引述自Houdini的网站,这种开放是“还没有被确认的,在浏览器上是不一致的,而且缺乏关键功能。”
例如,现在的浏览器的CSSOM不会展现你的跨域样式表,并且他会轻易丢弃掉任何他不认识的CSS规则或者声明,这意味着若是你想polyfill一个浏览器尚不支持的功能,你不能使用CSSOM。相反,你必须经过DOM,找到and/or标记,拿到CSS样式,解析、重写再把它添加到DOM上。
固然,更新DOM一般意味着整个浏览器必须从新完成全部的级联、布局、绘制和合成的步骤。

尽管彻底重绘一个页面对性能的影响看起来并不会特别大(特别是某些网站),可是思考一下这种事情发生的频率。若是你的polyfill逻辑是须要对滚动事件、窗口大小调整、鼠标动做、键盘事件进行响应的话——基本至关于任什么时候候都在改变——那么事情将会十分明显,有的时候甚至是接近极限,十分缓慢。
当你意识到今天绝大部分的CSSpolyfill包含他们本身的CSS解析器和他们本身的级联逻辑,你会发现情况变得更加的糟糕。又由于解析和级联都是十分复杂的事情,这些polyfills一般不是太大就是充满了bug。
简单的总结一下刚才我所说的:若是你想让你的浏览器(由于你给予的CSS)作一些它自身不支持的事情,那么你必需要亲自经过更新和修改DOM来伪造出这种效果。你在其他的渲染步骤里没有权限。
可是为何我会想改变浏览器的内部渲染引擎呢?
这对于我来讲,绝对是整篇文章中最重要的问题。因此若是你一直都是快速浏览的话,这部分必须缓慢并且仔细的阅读!
在看到最后一节后,我相信部分人会认为“我不须要这些!我只是想构建一个正常的网页。我并不想侵入个人浏览器内部去创造一些十分花哨的、试验性的甚至可能会形成问题的效果。”
若是你是这么想的话,我强烈建议你先退一步而后认真思考一下咱们这些年用在网站建设上面的技术。想要访问或者和浏览器的样式化过程挂钩并不仅是去建设花哨的样例——这是为开发者和框架做者提供动力去完成两件重要的事情:
-
正常化浏览器之间的差别
-
发明而且polyfill一些新功能让人们可使用。
若是你曾经使用一些JavaScript库诸如jQuery,那么你会从这种能力里面获益良多!事实上,这是现今几乎全部前端库或者框架的主要卖点。五个Github上面最流行的JavaScript和DOM资料库——AngularJS, D3, jQuery, React和Ember——都在减小跨浏览器间的差别上作了不少工做因此你不用去考虑他们。他们都只暴露出一个API,而后这个API正常工做。
如今,回想一下CSS和他那些跨浏览器问题。即便是最流行的CSS框架如Bootstrap和Foundation,尽管他们生成本身具备跨平台的兼容性,可是他们并无消除跨浏览器的bug——他们只是避免触发bug的作法。而CSS跨浏览器bug并不只仅是过去的问题。甚至在拥有新的布局模式的如[url=]flexbox[/url]的今天,咱们仍然会面对不少[url=]跨浏览器不兼容的问题[/url]。
底线是,想像一下若是你可使用任何CSS属性,而且知道他们必定会生效,在每一个浏览器里面表现都是同样,那么你的开发工做会变得多轻松。再想象一下,你在其余blog文章上面或者在会议上知道的新特性——如[url=]CSS grids[/url], [url=]CSS snap points[/url]和[url=]stickypositioning[/url]。若是你今天就可使用它们而且它们的性能表现的就像原生的CSS功能同样。而你全部须要作的就是从Github上面获取代码。
这就是Houdini的梦想。这就是他们指望的将来。
因此,即便你并不打算去写一个CSSpolyfill或者开发一个实验性的功能,你可能会想让其余人能够这么作——由于一旦这些polyfill存在,每一个人均可以从中获益。
Houdini有什么功能正在被研发中呢?
我在上面提到开发者对于浏览器的渲染过程没有什么控制权。事实上,惟一能够控制的是DOM而且一部分的CSSOM。
为了解决这个问题,Houdini工做组引入了几个新规范。这将会首次让开发者对渲染过程里的其余部分拥有访问的权利。下表展现了在新规范中渲染过程哪部分能够被修改。(注意灰色的规范是在计划中可是还没有被编写。)
下面几个部分将会简短地浏览一下每个新规范,介绍他们提供了什么。我应该注意到在这篇文章中有另一个规范未被说起;你能够从[url=]GitHubrepository of Houdini’s drafts[/url]上面观看完整的列表。
CSS解析器API
[url=]CSS解析器API[/url]还没有被编写;因此我所说的大部分都很容易被改变。可是基本想法是让开发者拓展CSS解析器而且告知他们新的结构——例如新的媒体规则、新的伪类、嵌套、@extends、@apply等等。
一旦解析器知道这些新的结构,它就能够把它们放到CSSOM里面的正确位置上去,而不是抛弃掉他们。
CSS属性和值API
CSS已经具备自定义属性了,就像[url=]我以前提到的那样[/url],我对他们被解开的可能性感到十分兴奋。而[url=]CSS属性和值API[/url]则在自定义属性上更进一步,经过添加类型让他变得更加有用。
在自定义属性上添加类型会带来不少好处,不过最大的卖点或许就是这些类型会让开发者能够为自定义属性添加transition和animate这些咱们今天不能使用的功能。
看一下如下例子:
<ignore_js_op>
在上面的代码中,若是night-theme类别添加到`元素上,页面上每一个具备--primary-theme-color属性的元素的值都会慢慢的从tomato转变成darkred`。若是你想在今天完成这些,你必需要手动地为每一个元素写transition,由于你不能对自定义属性进行transition变换。
这个API另外一个十分有但愿的特色是能够注册一个“应用钩”(apply hook),这让开发者能够在级联步骤完成后仍然能够修改一个自定义属性的值,这对于polyfill多是一个十分有用的功能。
CSS Typed OM
[url=]CSS Typed OM[/url]能够被认为是如今使用的CSSOM的第二个版本。他的目标是解决不少现有模型的问题而且会引入新的CSS解析器API和CSS属性和值API的特性。
Typed OM的另外一个主要目标是改进性能。将当前CSSOM的字符串值转化成有意义的类型化的JavaScript表达式会产生显著的性能提高。
CSS布局API
[url=]CSS布局API[/url]让开发者能够编写他们本身的模型。经过“布局模型”,基本上全部东西都能被传入到CSSdisplay属性中。这会让开发者第一次能够像原生的布局模型display:flex和display:table那样高效地进行布局。
做为一个示例,[url=]Masonry布局库[/url]展现了开发者开发者有多愿意去完成仅依靠CSS没法搭建的布局。尽管这些布局使人印象深入,可是不幸的是,他们充满了性能问题,特别是那些不那么强劲的设备上。
CSS布局API会给予开发者一个registerLayout方法来接受布局名称(这在稍后的会被用到)和一个JavaScript类来引入全部布局逻辑。下面是一个基本例子告诉你如何经过registerLayour来定义masonry:
<ignore_js_op>
若是你看不懂上面的例子,不要担忧。主要须要关心的是下面的代码。一旦你下载了masonry.js文件,而且将它添加到你的网站上,你能够像下面那样编写CSS而后他们就会工做:
<ignore_js_op>
html
CSS绘制API
CSS绘制API和上面的布局API十分类似。它提供了一个registerPatint方法,操做方式和registerLayout方法同样。开发者而后能够在CSS中任何地方须要CSS图像的地方使用paint()函数,只要传入他们注册的名称就好。
下面是一个简单绘制有颜色的圆的例子:
<ignore_js_op>
在CSS中它能够这样使用
<ignore_js_op>
前端
}如今,.bubble元素会展现一个蓝色的圆形做为背景。圆形自身会被放置在中间,而且大小回合元素自己同样,不管发生什么事。
Worklets
上面列举的许多规范都展现了代码示例(例如,registarLayout和registerPaint)。若是你好奇你应该在哪里放置这些代码,答案就是[url=]worklet[/url]脚本。
Worklets和web workers十分类似,他们都容许你引入脚本文件而且运行JavaScript代码。并且他能够在渲染过程当中的不一样地方被调用,而且独立于主线程。
Worklet脚本会为了保证高性能严重限制你能够用的操做类型。
合成滚动和动画
尽管仍然没有官方的[url=]合成滚动和动画[/url]规范,这仍然是实际上比较知名和高度受关注的Houdini功能。最终的API会容许开发者在合成worklet中执行逻辑运算,并且这是独立于主线程的,能够去修改一些指定的DOM元素属性。这些属性只会是那些能够在不须要重绘的状况下进行更改的属性。(如transform、opacity、scroll offset)。
这会让开发者能够创造高效的滚动动画或者基于输入的动画,如粘滚动的标题和时差效果。你能够在Github上挂看更多这个API尝试去解决的[url=]样例[/url]。
尽管还没有有官方的文档,Chrome上已经开始了实验性的开发。事实上,Chrome团队正在使用这个API最终会暴露的方法来添加[url=]CSS捕捉点(CSS snappoints)[/url]和[url=]粘定位(stickypositioning)[/url]。这是十分惊人的,由于这意味着Houdini的API足够高效,以致于新的Chrome特性依据他们来构建。若是你仍然惧怕Houdini不如原生的快,这个事实会说服你。
[url=]Surma[/url]录制了一个在Chrome上运行[url=]视频样例[/url]。这个demo模仿了Twitter原生移动应用的滚动标题欣慰。能够点击[url=]源码[/url]查看他是怎么工做的。
你如今能够作什么?
就像我以前提到的那样,我认为每一个网站构建的人都应该关注Houdini;他将会在将来让咱们生活的更加方便。即时你历来没有直接使用过Houdini规范,你也必然会使用一些基于他们完成的模块。
尽管这个将来不是立刻就到来,可是他会比不少人想象想的要接近。全部的主要浏览器厂商都参加了今年稍早时候悉尼举办的最新Houdini面对面会议。他们对于要作什么如何构建这些问题产生的分歧仍是比较少。
我认为的是,问题不是Houdini会否被实现,而是何时被实现。这也是须要大家的地方。
浏览器厂商,就像软件开发商同样,会对新功能进行分级。而这些优先级则通常都是用户对其的渴望程度。
因此,若是你关注web上面的样式和布局的拓展性。若是你但愿之后你能够不用等待漫长标准过程就能使用新的CSS功能。那么就和你使用的浏览器的开发者们说,告诉他们你想要这个功能。
原文连接:http://www.369cloud.com/devservce/index.html