淘宝彩票移动项目开发实践
转自:http://ued.taobao.com/blog/2012/10/11/%E6%B7%98%E5%AE%9D%E5%BD%A9%E7%A5%A8%E7%A7%BB%E5%8A%A8%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5/
作者按:如今越来越多的互联网产品开始在移动终端发力,终端产品越来越丰富。但是,平台差异带来的开发成本浪费很让人头疼。一段时间以来,淘宝彩票前端组也在努力寻求移动终端项目开发最佳实践,尽管诸多方面不甚成熟,但抛砖引玉,希望我们的总结整理会对大家有所启发。
淘宝彩票客户端产品目前有两条体系:
- 1、原生应用:包括iPhone和Andoird上原生的客户端应用
2、嵌入式应用:作为子应用的软件包形式提供,嵌入到第三方的客户端软件中,比如淘宝主站客户端以及支付宝客户端等
由于产品的共通性,这两类应用都是需要考虑较多复用性和开发成本的。在原生App中,有不少内容是可以用简单的HTML5来实现的,比如iPhone客户端中的“订单页”:
而在子应用的软件包里,则有更多的地方可以运用HTML5来实现,包括一些复杂的富交互。例如支付宝客户端中各彩种的实现:
App的形式
目前移动终端上的应用主要以Native App为主,这种应用的优势是:
- 1,性能快,体验好;
2,可访问本地资源,更有效的利用设备,节省流量;
3,并且已有一定规模(App Store),付费模式明朗。
缺点是:
- 1,开发成本高,移植性差;
2,所有发布需要经过App Store的审核。
当然,目前还存在一些Web App,用户可以直接通过浏览器来访问,例如Gmail。这类App的开发和维护的成本低,可以天然的在各种终端上执行,并且容易迭代更新,无需用户进行安装。不过就现阶段而言,无论从速度上还是交互上,用户体验与Native App的差距还是比较大的。既然两种App都各有利弊,那么我们就干脆将二者相结合:用原生控件做外壳和交互,保证流畅的用户体验和完整的推广渠道;使用HTML5来展示内容,保证内容的迅速迭代更新,即时响应用户需求。于是就诞生了Hybrid App,这也是目前最流行最合适的一种App形式。
对于前端工程师而言,在移动平台上没有了IE系列的困扰,HTML5的很多特性都可以大胆的运用。不同的是,我们需要设置一些针对移动终端的Meta属性,以及更合理的利用Media Query(主流移动设备的分辨率信息)。
JS框架的选择
找到适合使用HTML5的场景,这时就需要考虑JS框架的选择。首先需要明确的是,类似jQuery和YUI这种“重型”的库,由于包含了很多处理兼容性方面的代码,且API设计过于细致而显得太过庞大,并不适合移动端。我们可以选取一些专业的用于Mobile开发的JS类库,例如jQuery Mobile,Sencha Touch等。jQuery Mobile是目前最流行的一个移动开发的框架,文档丰富,社区活跃,有很多的UI控件供我们使用,并且提供对多页面的支持(通过Ajax方式读取内容,并提供页面切换的过渡动画)。我认为jQuery Mobile的最强大之处就在于其UI方面的支持,但这一部分恰恰不是我所需要的。Sencha Touch是ExtJs的移动版,对于不熟悉ExtJs的人来说有一定的学习成本。
我们选择了zepto.js作为底层库,使用sea.js进行模块的管理和发布,原因是基于CMD规范的模块文件最终需要打包入应用的软件包里, 或是打包后发布到线上;此外,我们使用backbone.js为基础的MVC架构,用来剥离应用的数据部分;使用underscore.js做为前端模板引擎(backbone重度依赖);使用iScroll.js为我们提供模拟滚动的功能。这些都是一些专业的“小库”,很适合移动端的开发。当然,具体情况需要具体分析,没有万能的框架,只有万能的开发者。如果时间允许,也可以自己来定制一套满足自身需求的基础库。毕竟在移动端,一切以 “精简”为主。
应用架构的选择
首先抛出两个小问题:
- 1, OPOA近两年来在互联网得到了广泛应用,相比于之前的多页面切换和跳转的方式,这个方法也更优雅,用户体验更好。那么在移动端,OPOA是否依旧适用 呢?
2, HTML5最大的优势就是跨平台,只需要开发一套代码,就可以完全通用于不同的终端。但是,真的一套代码就能“吃”尽所有移动终端么?
先解答第一个问题。其实我们在开始尝试的时候,完全是参照PC端的OPOA来进行的,把很多的内容都放在一个Page里面,通过URL或Hash的方式来管理页面的显示。但实践表明,在移动端这样做是有很大弊端的。首先,在PC上显示区域比较大,我们可以先给用户展示一个框架,然后在分块的去显示内容,但是移动终端由于屏幕变小,往往同时只能展示一个区域,那么我们首先要根据URL判断显示哪个区域,然后再去加载这个区域的内容, 这样一来,让本来在移动端就变慢了许多的页面更加的雪上加霜。其次,为了减少请求,我们通常会把大量的前端模板都塞到这个仅有的Page中,不仅导致页面体积变大,性能降低,而且维护困难。因此,我认为,在移动端最好的方式还是传统的多页面开发。
那么肯定有人会问,这样子的话岂不是会损失页面切换的流畅性,让用户不爽么。这个问题我们是可以解决的。第一就是采用jQuery Mobile的方式(Web App中非常适用),切换时用Ajax去请求新的内容,然后再渲染到页面中。这种方法在某些特定条件下会有问题:我们仍然需要使用URL来进行历史的管理,如果将这些页面作为静态文件打包在客户端中的话,在一些Android系统的手机中,硬件会将这些带后缀的文件当成一个完整的文件去查找(例如 index.html?page=XXX),然后发生错误。第二个方法就是在Hybrid App中,我们可以借助客户端来帮助我们进行页面的切换。你只需要告诉客户端即将要跳转的URL路径(可以是网络请求,也可以是本地静态文件),然后由客户端进行跳转。这样就可以在客户端代码里面设置Webview切换的动画效果,使客户端的整体风格更加的统一。
针对第二个问题,我们刚开始的目标就是用一套代码来自适应所有的客户端。结果发现,在iPhone和Android上,尽管风格差别较大,但是整体的结构和布局是很相似的,那么只需要设置两份CSS文件,再提供一份API,分别在两个平台上做实现就可以了,维护起来很方便;但是在iPad 上,由于布局和交互变化比较大,为了复用,不得不在原代码上增加分支,不但破环了原代码的完整性,而且维护时会产生一些意想不到的错误。这样就得不偿失了。因此,如果手机客户端和平板电脑客户端差异很大的话,最好还是分开单独进行处理,而不是为了“复用”而复用,大家可以根据具体的情况制定自己的策略。例如彩票的iPad客户端,我们就是纯粹基于HTML5为pad量身定做的:
Webview及其与HTML5的通信
Webview是手机中内置的一个基于webkit内核的SDK,是搭载Web页面的容器,也是负责Web页面和Native App之间相互通信的桥梁。在不同平台上Webview的实现是有较大差异的。
在Android平台中是支持JS方法和Java方法的直接调用的,我们通过下面的代码即可实现互相调用。
//将JAVA对象绑定到JavaScript中mWebView.addJavascriptInterface(new JsToJava(), 'stub');//在JavaScript中调用Java方法window.stub();
function invokedByJava(data){//do something}//在Java中调用JavaScript方法public void onClick(View v) {mWebView.loadUrl("javascript:invokedByJava('java_data')");}//打开webview,调用页面mWebView.loadUrl("file:///xxx.html");
但在iOS平台上,SDK没有原生提供JavaScript调用Native代码的API,只有反向调用的方法。要想在JavaScript中调用Native,一般有两种方法:一种是Phonegap采用的iframe方法,也是比较推荐的,如下所示;另一种是直接修改页面的location,在大部分情况是可用的,但是有时候会产生一些莫名其妙的错误。这两种方法的原理都是相同的:利用Webview去截获JS发起的特殊的网络请求,然后对其进行处理。
//Objective-C - (BOOL)webView:(UIWebView *)webViewshouldStartLoadWithRequest:(NSURLRequest *)requestnavigationType:(UIWebViewNavigationType)navigationType {NSURL * url = [request URL];if ([[url scheme] isEqualToString:@"gap"]) {//在这里做js调用native的事情//...//完成之后回调js//[webView stringByEvaluatingJavaScriptFromString:@"alert('done')"];return NO;}return YES; }//通知iPhone UIWebView加载url对应的资源,url格式为: gap:something function loadURL(url) {var iFrame;iFrame = document.createElement('iframe');iFrame.setAttribute('src', url);iFrame.setAttribute('style', 'display:none;');iFrame.setAttribute('height', '0px');iFrame.setAttribute('width', '0px');iFrame.setAttribute('frameborder', '0');document.body.appendChild(iFrame);//发起请求后将其从DOM上移除iFrame.parentNode.removeChild(iFrame);iFrame = null; };
除此之外,不同平台的Webview还需要进行一些特殊的设置,才能让其和原生的浏览器的行为表现相一致。例如:在Android Webview中,JavaScript和localStrorage都是默认禁止的,需要提前启用;Android的物理后退键默认是会关闭当前的Webview的,而不是执行history.back();在iOS5.0以下的系统中,设置格式检查的Meta属性会偶尔失效,需要在 Webview中直接关闭其格式检查等等。在D2沙龙的PPT中有详细的描述,大家有感兴趣的可以看下。
速度/性能
对于一个互联网产品的用户体验来说,速度和性能几乎是最重要的因素。但令人遗憾的是,这也是目前阻碍Web App发展的最大的障碍。原因主要有以下几个方面:
1 低端设备多,受硬件的限制。根据木桶原理,一个木桶的水量是受最短的板的限制的。与之类似,我们在衡量页面性能的时候,也需要看其在中低端机型上的表现,尤其是广大的Android千元智能机。如果Android所有的机型都能有Samsung Galaxy的表现,我们也就不用愁眉苦脸了,但是在更多时候,我们不得不为了在HTC野火上能够正常的展示而放弃在Samsung上看起来非常帅气的效果。
2 简化的浏览器实现。本来相比桌面版的浏览器,移动版的浏览器已经在功能上做了一些简化,性能上有些差距。但是,与原生的移动浏览器相比,Webview会更慢。下图为一个页面分别在Mobile Safari和Facebook的iPhone客户端中的运行结果,我们可以发现,UIWebView中的JS运行时间大概是Mobile Safari的3-4倍,这恐怕也是Facebook放弃HTML5转向原生应用的一个原因之一。
针对上述原因,我们总结出一些性能优化的小Tip:
- 1 用HTML5的离线存储和本地存储进行缓存,或者将页面直接打包到客户端中,减少在网络下载中的耗时。
2 减少DOM数量,尽可能少的使用position:relative,减少对DOM的操作
3 用CSS动画代替JS动画,在Android平台上可以平稳退化,放弃动画效果(包括CSS3动画)
4 避免GIF图片的使用(消耗内存)
5 如果只是在移动端使用的话,请使用iScroll-lite来代替iScroll(iScroll里面增加了很多额外的功能,比如在PC上模拟滚动),在允许的情况下,可以关闭滚动条(滚动条也是创建的DOM元素)
关于滚动,还有一些其他的想法,大家有兴趣可以一试:
- 1 将页面拆分成多个Webview,这样子在每个Webview中就都是原生的实现了,但会增加一些页面间互相通信的代价。
2 用Canvas来代替Scroll,但是文字的渲染可能会有些问题。
由于篇幅原因,这里就不赘述更详细的性能问题了~
移动终端的网络环境
移动应用最大的特点就是方便、随处可用。但无论是2G还是3G,我国目前的网络状况都难以满足移动应用的要求。相比于Native App,Web App除了要下载数据和图片外,还需要下载一些额外的js/css文件,这些动辄上百K的静态文件对于平均速度还不到10K的2G网络来说实在是太庞大了。 因此,目前最好的应用场景还是将页面打包到客户端中,版本变化时提醒用户让其主动进行更新。尽管这样会损失一部分web页面的灵活性。
调试
开发时的调试相对方便,可以基于浏览器进行。但开发环境和最终的执行环境还是有一些差异的,需要对终端的View中的“页面”进行调试,现在我们的做法是 “打点”,即使用一个Log代理控件给代码埋点,输出log,以此来辅助我们的调试。目前常用的工具有Weinre和JSconsole等。这些工具的原理是比较类似的:通过网络在其他机器上连接了一个调试的GUI,捕获待调试网页的JavaScript运行环境来查看代码输出或者对代码求值,并可以监控和修改调试目标的DOM和CSS样式。但是由于调试不是真正的发生在移动设备上,所以无法设置和捕捉断点进行debug。
在最新的iOS6中,Safari(仅限Mac桌面版)中自带了web检查器工具,可以让我们更方便的对iPhone/iPad上的Safari进行远程调试。
更多内容可以点击下载我在7月28日D2沙龙(北京场)的分享。
淘宝彩票移动项目开发实践相关推荐
- 淘宝商品库MySQL优化实践的学习
淘宝商品库MySQL优化实践的学习 淘宝商品库是淘宝网最核心的数据库之一,采用MySQL主备集群的架构,特点是数据量大且增长速度快,读多写少,对安全性要求高,并发请求高.由于MySQL最初的设计不是用 ...
- 基于Android的淘宝网手机客户端开发见解(配完整视频教程讲解)
淘宝网手机客户端是一个基于Android进行应用的项目,通过该客户端实现了注册功能.登陆.分页展示商品列表.能够对商品按名称进行模糊查询.能够对商品进行管理.能够对商品按价格排序.可以查看商品详细信息 ...
- flask python web开发 可视化开发_Python + Flask 项目开发实践系列六
今天开始我们讲讲Flask Web实践项目开发中的查看详情功能是如何实现的. Step1:html 部分 lists +="<tr>"+ //拼凑一段html片段 &q ...
- python web开发项目 源码_Python + Flask 项目开发实践系列七
对于 Python + Flask 这种灵活的web开发框架,在前面的六个系列文章中详细的进行了说明,主要讲到了页面的首页加载时的页面渲染,增加功能,删除功能,修改功能,查询功能,查询详情功能等一些页 ...
- 淘宝电商项目落地,从零开始搭建亿级系统架构笔记
电商亿级系统架构设计笔记,分为:基础篇.数据库篇.缓存篇.消息队列篇.分布式服务篇.维护篇.实战篇.通过学习这份笔记,你可以系统的学会从零开始搭建亿级系统架构.其中每篇中又有具体的设计实施的笔记供大家 ...
- java项目开发实践 pdf_Java项目开发实践 覃遵跃.pdf
高等学校软件工程专业校企深度合作系列实践教材 Java项目开发实践 总主编 周清平 主 编 覃遵跃 副主编 陈园琼 张彬连 彭耶萍 王新峰 ( ) 图书在版编目 CIP 数据 / 高等学校软件工程专业 ...
- 软件工程案例教程答案(第三版)韩万江 姜立新 编著 课后题答案 (软件项目开发实践)
软件工程案例教程 答案(第三版)韩万江 姜立新 编著 课后题答案 (软件项目开发实践) 第一章 课后答案 一.填空题 二.判断题 三.选择题 第二章 课后答案 一.填空题 二.判断题 三.选择题 第三 ...
- Scrum项目开发实践思维导图
# Scrum项目开发实践思维导图 ## 一.产品规划 ### 1.1. 目标设定 - 产品愿景 - 目标设定 - 战略规划 - 产品路线图 ### 1.2. 用户调研 - 用户故事 - 用户旅程地图 ...
- 霍常亮淘宝客教你开发app第9节:uniapp核心知识点
霍常亮淘宝客教你开发app第9节:uniapp核心知识点 每日更新一节课 之前录制的收费培训课程,现在免费分享给大家! 您的关注和点赞是我更新的最大动力! 更多教程以及合作请关注微信公众号:霍常亮创业 ...
最新文章
- asp.net performance
- 释疑の作业分割的理解
- iPhone 11跌至4439元?网友:虽是二手但用着很香
- 【转】NodeJs使用Mysql模块实现事务处理
- Axure Rp汉化安装
- 远程批量升级IE11
- 葡萄城报表模板库更新:新增6个行业、50张经典报表模板
- 黑苹果hd630显存7m_一次黑苹果的折腾记录——修改缓冲帧,解决显存只有7M,正确驱动Intel核显...
- 数字电路:数据选择器与译码器
- PHP 图片转PDF
- 音频噪声抑制(1):经典滤波器篇
- Jedis远程连接阿里云 Failed to create socket
- 什么是 Google Play服务
- 解决is exceeding the 65535 bytes limit问题
- 30天自制操作系统第8天harib05c
- matlab读取TXT文件数据,二进制文件数据
- 终于去看了麦兜响当当
- Linux下的USB驱动
- LeetCode 1348. 推文计数
- 国产男装「升级潮」下,九牧王、劲霸、海澜之家们顺利「上分」了吗?
热门文章
- java 验证码 字母_使用java生成字母验证码
- overflow:auto自动滚动到底部(vue)
- 计算机文件怎么取消隐藏文件,隐藏文件夹,教您电脑隐藏文件夹怎么恢复
- win10怎么隐藏桌面计算机,Win10隐藏秘技大公开
- java利用数组求平均值_Java程序使用数组计算平均值
- 黑白图片复原为彩色Picture Colorizer(图片着色器)
- 2018ACM-ICPC焦作站 补题
- 显示thread 1:signal SIGABRT 错误
- iOS完全免费的4个APP,良心安利!谁说便宜没好货
- 淘宝/天猫按图搜索商品API接口,以图搜商品API接口,图片搜索API接口