原文《mobile application Development: Web vs. native》,是由Andre CharlandBrian Leroux发布在《Communications of the Acm》的文章,深入探讨了移动领域Web开发和原生开发相关的问题。截止翻译,引用量320

1
Web应用程序的开发和部署比原生应用程序更便宜,但是它们能够匹配原生用户体验吗?

移动应用程序开发:Web VS. 原生

  短短几年前,大多数的移动设备,想要使用一个更贴切的词语来形容,是“哑的”。当然,也有一些早期的智能手机,但是他们要么是邮件集中,要么就是缺乏一个可以不用小尖笔就可以使用的先进触摸屏。附带一个有能力显示任何东西,不止是简单的文本,链接,或者是一个图像的像样的手机浏览器的就更少了.这意味着如果你有这些设备之一,你要么是一个沉迷于电子邮件的商人,要么是一个希望这是智能手机之年的最初的极客。之后苹果用iPhone的发布改变了一切,同时我们对于移动设备使用体验的预期被完全重设。

  最初对于第三方iPhone应用程序的计划是使用开放的Web技术。苹果甚至为它的Dashcode项目发布了工具。快速向前发展的三年,原生应用程序大大流行。通常,就工作性能的原因来看,相比较来说移动Web正在变得不是最适宜的。

  顺着这一条思考的路线有两个问题。首先,如果使用各自的原生语言来为不同平台构建应用程序是非常昂贵的。一个独立游戏开发者或者启动很有可能只可以支持一种设备,就像iPhone,但是一个IT部门必须支持它的用户的所有设备,即使它们不总是最新的和最好的。第二,原生应用程序适用于3D游戏或者图像处理时更快速的性能表现相关的争论,而且在一个使用Web技术良好构建的商业应用中有微小的、不引人注意的性能损失。

  就其本身而言,谷歌正在为使用Web技术去解决平台分裂化问题押注。谷歌负责工程的副总裁,声称

“连谷歌也没有足够的钱去支持所有的不同的移动平台—从苹果的应用程序商店黑莓Windows移动操作系统安卓,以及诺基亚平台的许多变种”。并且这是在惠普Web操作系统MeeGo和其他平台问世之前。

  在本文中,我们讨论Web和原生方法的一些优势和缺点,伴随着对于Web技术和它对应的原生同作用事务之间沟壑正在缩小的领域的特别关注。

原生代码 VS. Web代码

  实现一个软件应用程序从代码开始。在原生代码的情况下,大多数时候开发者通常用C语言系列,就像在开发iPhone应用程序的情况下。在我们在NitobiPhoneGap上的工作中,我们已经有足够的经验从一个原生开发者的角度去应对多样变化的移动平台。

  当然,由于多样变化的市场,或者是由于组织化的原因,大多数的开发者或者团队必须支持多个智能手机平台的应用程序。想要用原生代码写一个应用程序然后面对每一个单独的移动操作系统?没有问题,如果你的团队具有附带表格所展示的技能集。

  使事情变得更复杂的是实际的平台开发工具集之间的不同。有不同的工具、构建系统、应用程序编程接口,以及对于每个平台有不同能力的设备。事实上,这些操作系统共同拥有的唯一事物是它们都附带一个可以编程化访问原生代码的移动浏览器。

  每个平台都允许我们实例化一个浏览器实例,更简洁,并且可以使用它的JavaScript接口与原生代码相互配合。从Webview中我们可以通过JavaScript调用原生代码。这种攻击作为PhoneGap技术开始成名,由Eric OesterleRob EllisBrock开创,于2008年在iPhone开发营iPhone操作系统下开发工具集而写。这种方法后来被移植到安卓黑莓,以及其他支持PhoneGap的平台。PhoneGap是一个开源的框架,它提供给开发者一个他们可以使用HTMLCSSJavaScript来开发移动应用程序的环境,并且仍然可以通过通用的JavaScript接口调用原生的设备特性传感器PhoneGap框架包含原生代码片段,用来和底层操作系统互相配合以及传递信息给运行在Webview容器中的JavaScript应用程序。如今,有对地理定位、加速度计的支持,以及其他的许多。

  那么原生代码到底是什么?它通常是编译型语言,比解释型语言例如JavaScript运行得更快。Webview浏览器使用HTMLCSS构建用户界面,具有不同程度的能力和成功。使用原生代码,我们可以通过专有的应用程序编程接口直接在屏幕上绘制像素,还可以抽象化通用的用户界面元素和控件。

  简而言之,我们在让JavaScript和编译型语言较量。如今,JavaScript持有它自己。这并不令人惊异——JavaScript虚拟机技术是如今新的浏览器战争的前线。微软谷歌苹果OperaMozilla都在激烈地反复迭代,竞争着完成实现。现在,通过一些基准Mozilla”蜘蛛-猴子“正在接近谷歌的V8引擎。苹果的JavaScriptCore,在大多数的WebKit浏览器(使用于数量最多的移动设备上)中建立,并介于其中。底线是所有主要参与者的沉重开支正在为这场JavaScript军备竞赛添火加柴。Ars Technica的基准图1是这些企业是如何推销自己的一个例子。

  JavaScript正在迅速地变得更快——如此得快,事实上,惠普的Palm Web操作系统2.0版本重写了它的服务层,原来是Java,现在是极其受欢迎的node.js平台,它是构建于谷歌的V8引擎上并且在更低的CPU消耗下有更好的性能表现(因此具有更长的电池使用时间)。我们所能见到的趋势是Web技术栈运行在低水平,并且相应地在今天数以百万计的设备上。

用户界面代码

  当谈到用户界面时,事情并不那么美好。大多数原生平台有通用用户界面控件和体验的极好的抽象。没有两个平台有一样的,甚至相似的用户界面模式,更不用说单独使用应用程序编程接口去实例化和访问它们。Web平台在大多数情况下是一致的,但是内建的或者开发工具集包含的控件的数量是有限的。你必须去自己开始工作。有时浏览器之间的不同会造成烦恼,但是至少在现代智能手机的世界中,大多数设备运行着最能干WebKit渲染引擎,而且它们之间只有微小的差异。

  不幸的是,对于Web来说,那些微小的差异正在变成大问题。举个例子,在iOS中,CSS位置属性不能正确地支持一个“xed”的值。(这曾是安卓中的一个问题,但是已经在最新的安卓2.2代码中被修正。)黑莓操作系统在6.0版本之前运行着一个完全神秘的浏览器,对于Web开发人员的心智健康造成很多辛劳,也遭受很多痛苦。幸运的是,RIM在6.0版本中已经解决了很多类似的事情,并且一般来说,事情会变得越来越好。

  一些操作系统包含一些叫做硬件加速的事物。iOS堆栈非常著名地支持了这个CSS转换的概念,这是关于Web框架如何顺畅地在视图状态之间转换。这是一个首先在Dashcode中被发明的技术。它由David Kaneda煞费苦心地反向工程化,在jQTouch上开创,并且后来在Sencha Touch发布。它们都是令人难以置信的Web项目,同时也是当开发人员推动边界时什么事情可以被完成的例子。

  当我们首先开始利用这些下一代的移动浏览器时,没有什么框架可以在不同设备之间正确地工作。如今有超过20种的移动框架,并且相关支持正在被快速地添加到已有的文档对象模型库中——不止是John ResigjQuery,还有jQuery移动版;那些代码正在被不断地完善,并且每天都在为更多的设备添加支持。有了这些类似的工具,从一个单独的面向Web的代码库去支持多个目标变得越来越容易。

  当把Web技术栈和原生代码比较时,快速执行和漂亮的用户界面并不是故事的全部。Web技术存在于沙盒,这也是原生代码可以访问的低级API的笼子——可以访问设备存储、传感器和数据的API。但是这一沟壑也正在被弥合。如今大多数移动浏览器支持地理定位,举个例子,iOS最近增加了加速度计和一些其他的HTML5应用程序编程接口。考虑到W3C有一个设备API工作组,就好像我们在不久的将来将会看到许多连至浏览器的API。如果这个很近的将来不是足够短的话,现在你可以使用PhoneGap来获取这些API。

  当然,Web技术堆栈(HTML/CSS/JS)本身就是用原生代码实现的。原生层和浏览器之间的距离就只是一个编译而已。换句话说,如果你想给一个浏览器添加一个原生的能力,你也可以桥接它或者重新编译这个浏览器以获得那个能力。如果一个浏览器不支持一个原生的能力,不是因为它确实不能,也不是因为它不愿意;它只是意味着它尚未完成。

用户体验:上下文环境与实现

  另一个对原生和Web移动应用程序开发都有重大影响的领域是用户体验,我们使用这个术语来描述用户使用一个软件应用程序期间的全面的体验。用户体验甚至可以扩展到应用程序之外。举个例子,我们在某些情况下发送通知去唤醒一个应用程序,比如一个地理位置的变化,或者产生一个专用的应用程序去处理不同的应用方面。显然,一个成功的用户体验是采用成功应用的关键。

  一般来说,一个移动软件项目的用户体验可以分为两个主要类别:

  • 环境

  元素必须能够被理解,但是不能被改变或者被控制。这些包括硬件功能,平台能力和用户界面规范,以及应用程序被使用的环境。

  • 实现

  在一个应用程序中可以被控制的元素,比如性能,设计以及集成平台特性,例如加速度计的数据或者通知。

  你的应用程序将被使用的环境影响着用户的预期。单独的应用的使用环境可能和一个用户与用户之间互相影响的应用或者一个单独的平台完全不同。我们其实不是在谈论一个环境;我们在谈论多个环境。让我们看看定义一个成功的移动应用程序必须具备的环境的东西究竟有什么。

  硬件。安卓设备的生态系统是一个多样化环境的极好的例子,设备在显示的多方面(物理尺寸、颜色深度、屏幕分辨率、像素密度、长宽比)、输入(轨迹球、触摸屏、物理键盘、麦克风和摄像头)以及能力方面(处理能力、存储、天线等等)显著多样化。

  这些属性的结合极大地影响着你的应用程序将如何展示,以及用户可能选择的与它交互的方法的范围。如果如今不存在一个特定的组合,明天也将很有可能出现。一个成功的应用程序必须考虑所有这些硬件设备相关的习惯。

  平台的约定。每个平台都有它自己的用户界面约定,通常在人机界面指南文档中描述,在操作系统界面证实。移动Web浏览器的多样性提供了一个典型的例子来展示这些约定可以是怎么样得不同:

  一个公共的用户期望是浏览器中“返回”的能力。iOS使用一个虚拟按钮来实现它;安卓和黑莓设备依赖一个物理实体返回按钮;Web操作系统使用一个返回按钮和一个返回手势。无论方法是什么,用户希望在你的应用程序中他们可以“返回”。

  用户也期望一个环境菜单。在安卓和黑莓的默认浏览器中,环境菜单通过一个被设立在屏幕底部的物理按键打开,接近拇指的自然的位置。在iOS和Web操作系统中环境菜单通过位于屏幕底部靠近拇指固定存在的虚拟标签栏来打开。这个固定存在于屏幕底部的标签栏在非iOS和Web OS设备中经常产生一个很差的体验因为用户会很容易地误触他们的环境菜单或者返回按钮,造成应用程序意外地被关闭。这些是原生和Web应用程序都必须考虑的限制。

  开发人员必须考虑对数据和用户都有良好意义的方法。HTML5不支持菜单元素的概念,所以一个通用的抽象在这里就是可行的,但是它尚未完成。

  环境是最大的不确定因素。现在是白天还是夜晚?用户在站着还是坐着?站定还是移动中?一个手空闲还是两个手?在一个繁忙的地方吗?可变性是无限的。

  它指引着我们什么方向?从环境中传出来的期望并不是天生跨平台的。原生和Web实现都必须提供设计和代码去支持这些期望。对于Web开发人员来说好消息是他们可以依靠一个熟悉模式在Web技术堆栈中满足用户期望。

  实现。为了产生最优的可行的用户体验,实现部分必须在设计和代码上兼顾支持由一个特定的用户环境产生的期望。

性能:软件开发的妖怪

  毫无疑问,性能是一份良好用户体验的基石。就像安全性,它是最被误解的,也是软件开发人员的限制使用的替罪羊。不难听到开发人员拒绝一份想法的同时碎碎念:“我们不能这么做,这会对性能造成负面影响。”很少量化,但频繁地引用着一句话:“性能是软件开发的妖怪。”我们如何量化性能?延迟是性能的一种形式。执行,一个操作完成需要的时间,是另一种。我们会分开解决这些事情。

  在移动开发世界中,延迟是一个重要的考虑点。不管它是原生应用程序还是一个Web应用程序,在下载一个应用程序以及它通过网络耗费或发布数据时,都会有性能损失。显然,负载越小,应用程序越快速。

  使用JavaScript对象表示法JSON)格式的数据是一个很棒的想法,因为与一个等价的XML负载相比较来说,它会导致更少的数据负载,这取决于XML是如何格式化的。在另一方面,当我们要返回插入Web页面的HTML代码片段,使用XML形式的数据,而非返回JSON形式的数据,当线路较短时,需要使用JavaScript去转换成HTML片段。你面对的情形会不尽相同。基准测试是唯一可以确定结果的方式。

  另一个延迟问题是代码初始化时。一旦我们将代码写入内存,它就持续地需要被解析。在这个过程中会有明显的性能损失。我们可以仿造它,并且使用确定或不确定的过程指标来提高对性能的感知。

  执行时间,当然,是一个性能的关键指标。解释执行代码(就像我们为Web使用JavaScript)时,有越多的代码需要解释执行,执行时间就越长。Web技术堆栈中还有一些事情需要追赶着去做。JavaScript,它的所有性能的飞跃,仍然比原生的组件要慢。另一方面,一个程序员为了多种移动设备,使用原生的编译型语言去书写类似的逻辑所花费的时间可能是值得的,相对执行时的损耗来说;然而,这实实在在需要更多的维护,相比起使用JavaScript书写,可在多种设备运行的代码来说,同时也许每个平台需要些许调整。更少的代码通常意味着更少和更容易的维护。

  有一句话这么讲:“代码的少量对于期待一个良好界面的终端用户来说是无关紧要的。”开发人员的权衡有一个巨大的代码基础,经常容易变得更大,考虑到对多个原生平台的支持。在原生代码的世界中,最大的挑战是重复实现多个目标。在Web的世界中,最大的挑战是尽可能多地限制你的足迹,以产生良好的用户体验。这并不是说一个用户界面可以满足所有的环境。而是,应用程序逻辑的主体在一份代码基础中,然后特定的设备、特定的UI习语可以使用情景化的代码来实现。因此你可以实现不同的功能和用户体验,以适应某个特定设备用户的期望。举个例子,安卓和黑莓设备有物理实体的返回、菜单按钮,而这个iOS设备并没有。

  另一个需要记住的重点是即使移动设备工业正在快速的汇集于Web开发工具集,即标准的HTML渲染引擎,每种设备和操作系统都有一个稍微不同的WebKit风格。这意味着你应该期待开发变得和如今的跨浏览器Web开发相似。值得庆幸的是,有许多类库例如jQuery移动Sencha Touch, 和SproutCore在试图解决这个问题。

  所有关于代码延迟和执行的讨论意味着要对你的应用开发主动性的商业目标采取强硬的态度。支持数据装饰是最实用的方法。渐变、阴影、凹凸变化、压花、高亮、圆角以及柏林噪音并不能使应用的可用性增强——它们并不满足商业要求,但他们影响性能。特别是CSS渐变,是移动世界中真正的魔鬼。你需要决定你的目标是什么:看起来整洁还是为数据发布、获取提供一个有用的界面。你在一些平台上通过使用原生代码优化(通常是硬件加速)像素绘制胜过了这些能力中的一部分。这并不是说这些影响不可能实现,而是说他们被明智地使用,也就是当他们能提升、并且不分离用户体验时。提供一个在市场上获得成功的用户体验是有可能的;要求的仅仅是合适的移动开发技术,以及考虑了环境约束的良好的用户体验设计技巧。

可爱的反弹和美丽的设计

  当然,美丽的设计很重要。从美学到无形资产,例如一个良好程序的结构,软件设计者必须致力于伟大的设计,并且立足于已经到位的实践。通过动力学物理滑动,可爱的反弹,放松,并且基于此构建有活力的用户界面,它是令人觉得真实的,并且使用它是一件乐事。这是一个原生控制特别良好的领域。

  我们还没有使用Web技术圆满地解决原生的滑动问题。但是已经有了许多的尝试:iScroll, TouchScroll, GloveBox, Sencha, 以及jQuery Mobile. 所有这些都致力于解决滑动的问题,但是并没有像原生设备一样那样良好地解决。甚至谷歌的移动团队也在致力于发布一个这个问题的解决办法。毋庸置疑,这是PhoneGap团队最常听到的抱怨,在WebKit出现这个问题之前很久我们就已经是它的问题修复者。谷歌移动团队最近已经发布了基于浏览器和平台的WebKit的解决方式以及代码。

  这是纲要。Web技术栈还没有能够达到原生代码可以获得的优良性能表现级别,但正在逐步接近。我们有自信Web技术将会逐渐无区别于原生体验。同时,Web开发者必须在专注于交付数据的同时提高装饰的工作能力。

展望未来

  Web和原生在这场辩论中对抗彼此越多,导致的结果很可能是混合的解决方案。或许我们将会看到计算机固有的网络化并且(这是我个人的真诚希望)对于任何人都可以免费访问。我们已经看到原生Web的迹象:WebGL最近证实浏览器运行3D游戏是可行的,甚至运行Quake III!

  同时,软件制造商必须平衡Web和原生的对抗,在软件主要的目标、开发、商业现实以及Web技术在不久将来可以提供的机会的基础上。好消息是直到所有技术都被整合进浏览器之前,诸如PhoneGap这类的机构可以帮助弥合鸿沟。我鼓励开发人员不要简单地定义软件开发的趋势,而是实现他们!如果Web不满足你的程序所特定需求的能力,你就获得了一个令人激动的做出贡献的机会,为了弥合Web和原生之间鸿沟的过程做出贡献。

译文:Halo