原作链接:The Making of Fastbook: An HTML5 Love Story

fastbook-hero

当我们开始这个现在被称为Sencha的东西时,我们对WEB打了一个赌:我们赌当今的应用程序开发仅仅需要浏览器、一组优秀的框架和一套出色的工具。有了这三样武器,我们知道开发者们能够开发出用户喜欢的应用程序。HTML5的问世让这一切变得更加有趣,它让开发者们拥有更多的工具来把浏览器当作应用开发的平台,而不仅是页面渲染引擎。面对这一机遇,开发者们激流勇进,应用程序如雨后春笋般涌现出来——包括桌面和移动端——充分发挥了HTML5使用WEB标准创建让人惊叹的应用程序的能力。

所以,当马克·扎克伯格说“HTML5还没有准备好”时,我们对此是不敢苟同的。

我们认为:Facebook的移动应用反应迟钝并不能归咎于HTML5。我们清楚智能手机上的浏览器有多强大,以及HTML5向我们展现了多么丰富的能力。我们看到了最新一代的移动设备——至少运行着iOS 5 和 Android 4.1 ——正推动HTML5不断实现更加出色的表现。但是最重要的是,我们已经看到我们的用户使用HTML5创造出了多么不可思议的应用。

“So, when Mark Zuckerberg said HTML5 wasn’t ready, we took a little offense to the comment.”

对于为什么Facebook的移动团队遇到了问题,我们有着各自的疑虑,因为这印证了一种常见的模式。在Sencha,我们开发框架和工具供应用程序开发者们使用,所以我们对使用HTML5开发应用程序的团队有很深入的了解。当一个团队在使用HTML5开发遭遇问题时,通常是因为他们用开发“网站”的方法来开发应用程序,而且经常没有使用正确的工具和架构。我们怀疑这正是Facebook的HTML5应用遭遇问题的原因所在。应用程序表现出了它的常见症状——缓慢的加载、新鲜事(原文:News Feed)中不连续的用户体验、低帧率。

在任何情况下,我们都认为HTML5实际上已经准备好了,而且我们想证明这个事实。所以我们决定以在业余时间重新建设Facebook移动应用中具有挑战性的部分为己任。今天,我们向你介绍Sencha Fastbook,用技术证明HTML5可以有多快,并且对于应对最棘手的应用程序挑战,它已经迫不及待了。

接下来这段四分钟的视频带你快速领略Sencha Fastbook,并且将我们的HTML5应用和iOS以及Android上的本地Facebook应用(5.2版本和1.9.12版本是我们制作此视频时(12月10日)的最新版本)面对面地一决高下。本文的剩余部分我们将深入探讨Fastbook的技术细节。
(本译文中的“本地”二字即原文中的“native”,似乎也译作“原生”,译者知识浅薄,暂时分不清楚,在此且用“本地”)

(译者:视频在vimeo上,所以……可能需要一些功夫才能看到……地址:http://player.vimeo.com/video/55486684?title=0&byline=0&badge=0)

近距离观察“本地”Facebook 应用程序

扎克伯格称HTML5“尚未准备好(原文:just wasn’t there)”,于是我们决定深入地研究一下iOS上的最新版Facebook 本地应用,以尽量准确地理解扎克伯格的“尚未准备好”,并以此作为我们的工程的开始。我们把一部iPhone手机连接到了电脑上的WEB调试程序,以观察Facebook应用程序所产生的HTTP流量。最让我们感到震惊的是:这个应用程序的很大一部分都是由原始的HTML页面构成的。新鲜事(原文:News Feed)和资料页面已经转换为本地程序,但是程序的许多其他用户界面只是简单地向 m.facebook.com 发送了HTTP GET请求。目前的“本地”Facebook应用实际是一个混合的WEB/本地应用:由 m.facebook.com 渲染、由UIWebView呈现的内容,和本地的 Objective C 组件混合在一起。

重新实现新鲜事板块

在我们看到了本地Facebook应用是怎样工作的之后,我们清楚地认识到,用户体验中最难实现的部分是新鲜事(原文:News Feed,下同)。因为这需要处理由十亿用户以完全无法预料的方式上传的无穷无尽的内容,这对于最老练的开发者们都是一个棘手的问题,无论他们使用何种技术来实现。

当我们使用HTML5重新实现新鲜事时,我们真心希望我们能够确保它应有的流畅体验。为此我们进一步扩充和增强了Sencha Touch框架的核心。

首先我们通过实现一个无穷列表组件来处理未知大小的内容。仅仅很小的一组DOM节点就构成了实际可见的屏幕区域。在加载需要加载之前/之后的内容时,这组节点将不断反复地被使用。因此,不管存储器中的数据有多少,内存的使用都被降到了最小。实现这一点并不难。要在处理新鲜事这样复杂和多种多样的数据时保持快速才是真正的挑战。瓶颈在于浏览器需要运行的核心进程:布局和整合。

开发框架的经验告诉我们,即便一个小模块自身能够很好的运行,但是当你把它放到一个比它本身大得多的应用中时,它的性能往往会捉襟见肘。随着应用程序的逐渐庞大,DOM(文档对象模型)树也在不断长大;随着DOM树越来越大,浏览器计算布局所需的时间也就越来越长,程序性能就会下降。而且,随着可见内容的增多,浏览器整合每个布局(译者:可能是指上一段所说的用来构成可视区域而重复使用一组DOM节点)时的性能也会明显地下降。我们需要能够让应用在庞大的DOM树下更加强健有力。

fastbook-1
fastbook-2-medium-size
将本地Facebook应用和我们的Sencha Fastbook应用做面对面的比较

Fastbook是第一个使用全新的“沙盒容器”(原文:Sandbox Container)来分离复杂的视图,将其放到自己的内嵌框架(iframe)中渲染,从而分割整个DOM树的。这种特殊的容器不需要任何其他的应用程序层的处理,从而实现了与开发者的无缝对接(即所有添加到这个容器中的组件都将自动“沙盒化”(原文:sandboxed))。但是这也是有代价的:事件、定位、样式和JavaScript代码不得不作为主窗口(原文:parent window)和沙盒(原文:child sandboxes)之间的代理。这是很复杂的,所以如果没有一个强劲且架构合理的框架,这是很难实现的。沙盒允许布局以分离的方式呈现,这样可以让主体的DOM树尽可能的轻便。想要取得平衡以使其发挥最大功力,使用沙盒容器必须聪明得当。

就Fastbook而言,新鲜事、时间轴(原文:Timeline)和故事(原文:Story)的界面是单独在各自的沙盒中呈现的。由于在渲染内容时所有的DOM元素都以很高的频率重复利用,大量的reflow(译者:浏览器渲染样式时改变布局的一种行为。译者google了reflow的相关资料,暂且如此理解。欢迎指正!)是不可避免的。关键在于让这个进程尽可能少的占用资源。使用沙盒容器的方法让新鲜事表现得仿佛是单独运行的,而实际上它仍然只是一个比它大的多的DOM树的一部分。

“Sandboxing enables the News Feed to perform as if it is standalone, while actually is still a part of the much bigger DOM tree.”

接下来,我们将更深层的部分集成到了我们的TaskQueue(译者:任务队列),即Sencha Touch最近引入的一个特性。TaskQueue防止了对DOM树的交叉反复的读写请求,消除了任何不必要的呈现。结合新的沙盒技术,这一特性显著地减少了呈现复杂视图如时间轴、新鲜事时的性能代价。

紧接着我们添加了AnimationQueue(译者:动画队列),这是一个全新的类,能够对所有的动画和事件做出响应,同时能够将较繁重的任务安排在之后CPU较空闲的时候执行。它角色就像是框架的交通警察,权衡着不同操作的优先级,确保应用程序保持响应。当应用在执行动画时,会暂停较低优先级的功能。当程序空闲时,AnimationQueue再执行那些较低优先级的任务。比如,当用户在快速地滑动新鲜事页面时,图片的加载和渲染会被暂停,直至程序空闲,以此提升滑动页面时的体验。并且,一个高速的计时器会把较繁重的任务以无间隔的方式渐次地释放执行。这样保证了触屏事件一直都可以尽快地得到响应。

另一方面,你不想禁止一些功能性的类,比如获取更多数据来显示在列表中。为了确保这样不减慢屏幕的滑动,我们使用了Web Workers(HTML5的新特性,是运行在后台的JavaScript,独立于其他脚本,不会影响页面的性能)。这样就把XHR/RPC通信和UI线程分离开来。使用Web Workers节省网络请求成本和JSON编码/解码在现如今的多核设备上有着广泛的应用。

以上就是我们在创造Fastbook时的技术要点,正是它们让我们能够使用纯净的开放标准的WEB技术造就Fastbook的出色表现。借此我们向你展示了如何使用HTML5的各种特性来实现一个像Fastbook一样惊人的应用,这也让我们兴奋异常。

福利

(原文:Bonus Points)
一个有趣的事情是,在我们研究iOS上的本地Facebook应用的网络性能时,我们发现API调用返回了大量的原始数据给客户端。为了呈现新鲜事中的条目而向https://graph.facebook.com/graphql/ 发起的API调用,就是一个典型的例子。平均每10个条目就要传送15KB到20KB的用gzip压缩过的JSON数据,其中大多数并没有真的被显示出来。

为了演示怎样能够优化网络传输,我们设立了一个代理服务器,用来清理和解析从Facebook FQL API返回的原始数据。于是,在呈现相同的内容时,Fastbook传输的数据量远小于本地应用程序:在显示新鲜事时,最少仅传送了相当于本地应用10%的数据。代理服务器允许我们卸载一些更加普通的任务,例如内容格式化,并将其筛选到服务器端。

同时,你可能注意到了本地iOS应用和Fastbook在滚动持续时间(原文:scrolling declaration time)上的差别。在本地应用中,滚动持续了大约3秒。我们决定增加摩擦力来将动画持续时间减少至1.4秒。这样不仅使得页面内容可以更快地加载就绪,而且为程序腾出了更多的空闲时间,以在用户阅读现有内容时缓存更多的条目供稍后阅读。

亲身体验一下吧

(原文:Try It Yourself)
Fastbook不是Facebook应用的替代品。它是一个技术示例,向世人展示,只要使用正确的方法,辅以合适的框架和工具,开发者们能够用HTML5来做什么。如果你一直都想知道,HTML5已经准备好了吗?把Fastbook下载到智能手机(我们推荐至少为iOS 5或Android 4.1)上试试吧。你会发现,当你把浏览器当作一个应用程序开发平台来看待,并且充分利用HTML5的强大特性时,即使是最复杂的应用程序也可以使用HTML5来实现。

快快动手敲起来!

(原文:Shut Up and Code)
如果你被激励了,想要和我们一起向世人展示HTML5能做什么,我们邀请你参与我们今天发起的“HTML5已准备好”应用程序辩论会(HTML5 Is Ready App Contest)。我们提供超过$20,000的经费和先进设备,让那些有志于使用HTML5辅以强大工具向人们展示让人叹为观止的应用的开发者大展拳脚。完整的规则和奖励在这里

(译者:哈哈。胡子

  菜鸟译制,差错难免,欢迎指正!


(转载请注明出处:http://blog.hudidit.com/?p=270
(满怀敬意地再次附上原作链接