3 其他机制
3.1 新渲染机制
为了移动领域更好的用户体验,渲染机制所做的改进主要是提升渲染性能来增加响应的速度,甚至不惜牺牲一些跟规范定义的行为不一致的地方。在这一小节中主要介绍三个方面的技术,其一是Tiled Backing Store,其二是线程化渲染,其三是快速移动翻页。
目前主流的移动设备上,触控操作是必不可少的用户交互方式。同桌面系统不一样的是,网页的渲染结果需要对用户的响应度有很高的要求。不幸的是,移动设备的能力比桌面机器的能力还是要差一些,为此,在最早的QtWebKit中引入了一项技术,这就是Tiled Backing Store机制,其核心思想是使用后端的缓存技术来预先绘制网页和减少网页的重绘动作,也就是使用空间换时间的典型思路。
最初这一思路出现在软件渲染中的,使用CPU分成瓦片块(Tile)的内存来保存绘制的网页内容,也就是图13-5中所示的这样,不同点在于它是使用CPU来分配并保存这些瓦片块,而且通常会超过视窗(Viewport)大小,也许会是它的两倍。这同样是一种典型的用空间换时间的做法。
图13-5 使用Tiled Backing Store渲染技术的网页
该图跟图8-18有类似之处,只是该图中的后端存储表示的是渲染中的一层,而这里是指这个网页,因为这里是针对软件渲染机制,同时缓存的一个瓦片很容易被重复利用,因为每个瓦片大小一致,这一原理第8章中做过一些分析,区别在于这里不用担心GPU所能支持的纹理是否够大,因为这里使用CPU内存的缘故。不过目前这一技术已经有些过时,因为使用硬件加速渲染成为一种主流的方式,这一方法逐渐被抛弃,但是其思想还是很有意义的。
随着移动设备进入多核时代,如果渲染过程仅仅是由一个线程来完成,这不能不说是一个巨大的浪费。而且,同桌面系统强大的单核能力不同的是,因为耗电等原因,单核的能力明显处于一个稍差的阶段,所以将渲染过程分成若干个独立的步骤,然后使用不同的线程来完成其中的某个或者几个步骤可能成为未来WebKit(和Blink)渲染引擎一个重要的发展方向,特别对于移动领域来说尤为重要。读者可能会疑惑这些步骤之间依赖性是否非常强,是不是不可能或者很难达到这一效果,现实是一些过程已经被实现了,图13-6描述了Chromium的线程化合成过程。
图13-6 使用线程化的合成器来渲染网页
因为合成阶段是依赖之前阶段绘制的各个层结果,所以主要的神秘之处在于图8-16所设计使用的Layer树和LayerImpl树,其中Layer树在主线程,而LayerImpl树工作在一个专门用来渲染的线程,两者通过线程通信来进行同步,这样就独立开来,从而提升网页滚动时候的用户体验,因为这时主要使用合成器来完成新网页的显示。同时,合成工作并不会阻止Renderer进程的主线程,也就是WebKit工作的线程。未来,Chromium应该也不会满足目前的优化,可能会把这个渲染过程都通过线程化来进行,甚至今后JavaScript代码也能够支持多线程编程,这能够有效提升JavaScript代码的能力。
因为移动领域还存在一些能力的局限性,但WebKit为了更好的用户体验,也做出了一些妥协,如快速滚动机制(Fast Mobile Scrolling)。先看背景,下面是CSS中的一个规则。
body { background-image: url(background.gif); background-repeat:repeat-x; background-attachment: fixed; }
这段代码的含义是当body元素在滚动的时候,它背后的背景图片一直固定在文字后面,而不会随着网页的滚动而滚动,如图13-7所示的结果。图中显示了三张背景图片,因为设置的只是在X方向的重复(避免Y方向重复,这样滚动的时候不容易看出效果),所以当发生滚动的时候,这三张图片总是以背景的方式出现在该滚动区域的最上部分,而不会随着内容的滚动而发生滚动。
图13-7 使用“Fixed”模式的背景图片
这一CSS的样式设置会触发WebKit进入一种称为“Slow Repaint(慢速重绘)”的模式,去以避免一种称为“Rendering Artifacts”的现象(前面一帧的某些数据出现在后面的绘制中)。因为WebKit要在快速滚动中绘制一个静止的元素非常困难,只能通过慢速重绘,而重绘会降低网页的性能,特别是降低界面的响应度。然而,在移动设备上,对于用户交互的响应度要求特别高,降低响应度就是一个大问题。但解决问题的方式很简单,就是取消该属性的设置,这的确是一个折中的方案。
3.2 其他机制
为了更好地支持移动设备,WebKit做了大量的工作,引入了一些新的机制,例如,在本节中,主要介绍两种技术,其一是Application Cache,其二是Frame Flatterning技术,也就是处理网页的多框结构。更多内容,有兴趣的读者可以通过“http://trac.webkit.org/wiki/Mobile%20Features%20Talk”来了解一些重要的功能,限于篇幅,这里不再一一介绍。
移动设备因为其移动的特性,需要能够提供离线浏览网页对的内容,而应用缓存(Application Cache)这一新支持的机制能够支持离线浏览,同时还能够加速资源的访问并加快启动速度。它的基本思想是使用缓存机制并缓存那些需要保存在本地的资源,开发者可以现实指定哪些是需要缓存的资源,并且使用起来非常简单。
<html manifest="app.appcache"> … </html>
只是需要在“html”标签上加入属性“manifest”,指向一个文件,该文件格式如图13-8所示,以此来定义哪些资源需要缓存。该例子表明,它要缓存4个文件,这样在离线情况下,用户也能使用该网页并进行离线访问。
图13-8 “app.appcache”文件的内容
不仅如此,规范还提供了接口来控制和访问网页中应用缓存的状态信息等,下面的例子就是使用规范定义的接口来更新缓存的内容。首先是注册一个回调函数,当更新后触发该函数,如果更新成功,那么需要将旧的缓存清除掉,填充新的缓存内容,这就是swapCache函数的作用,如示例代码13-3,在代码最后,调用update函数就可以完成触发更新资源的目的了。有了这些,离线使用就变得很容易。
示例代码13-3 使用应用缓存接口来更新缓存内容
var appCache = window.applicationCache; appCache.addEventListener("updateready", function(event) { if (appCache.status == appCache.UPDATEREADY) { appCache.swapCache(); } else { … } }); // 重新下载缓存的资源 appCache.update();
接下来介绍框结构在移动设备上的特殊处理。第3章已经介绍过网页的框结构,其中讲到网页可能包含多个框,每个框都可以包含一个滚动条(如果该框在布局中的大小要比实际的内容小),也就是框内部是可以滚动的。当光标在该框中的时候,滚动鼠标中键能够滚动该框的内容。但是在移动设备上,因为屏幕和触控的缘故,用户可能不知道需要滚动网页还是框,因此,iframe和frameset等多框结构很难在移动设备上使用,为此,WebKit使用了一种称为“Frameset Flatterning”的技术,该技术的含义是将框中的内容全部显示在网页中,通俗来讲就是将框中的内容平铺在网页中,而不用设置滚动条,这也就意味着,用户只是滚动网页,当然框中的内容也包含在网页中,也会随着网页的滚动而发生变化。
上面介绍的这些技术都在WebKit中得到了很好的支持,开发者可以借助于这些技术开发出用户体验更好的网页和Web应用。除了WebKit等渲染引擎为移动领域做了众多的工作,在Web开发领域,也有众多的JavaScript框架为移动领域量身设计了JavaScript库,现在较为流行的如jQuery Mobile、Sencha Touch等,它们当然也使用了上面介绍的一些技术,如HTML5 Touch Events、移动上的用户界面等。