资深架构师、技术创业家。两者共同的特点是“够牛X”。正因此,很多奋战在第一线的程序师们会将他们定位为自己的目标,并期望可以向他们学习、取经。针对这个广泛存在的诉求,一场别开生面的京、广、杭三城“ 极客 & 创客大宴 ”悄然展开—— 9 月 19 日,又拍云 Open Talk 同时登陆北京、广州、杭州,一场三地联办的大型技术主题沙龙拉开帷幕。

这场名为“技术的三城形态”的实战分享会力邀了新浪、七乐康、河狸家、海蜜、贝贝、图普科技、甘果移动、爱拍、淘粉吧的技术负责人、企业掌门人“压阵”,好东西自不会少。慕名而来的三地开发者们聆听了一场干货满满的技术与创业讲堂。北京活动的主题为《移动应用系统架构设计》,七乐康高级技术总监曲毅在活动上做了题为《crow5引擎技术自动化编程》。

image.png

很高兴与大家一同分享 HTML5 技术在移动互联网的一些具体应用。

今天主要分享的是移动的一些技术,尤其是编程。我将以早期电商从事过的经验给大家介绍一下引擎的技术。

我们做一些移动端的东西都比较割裂,除了 H5 客户端,还有 Android 客户端,iOS 客户端,未来其实也是一个客户端,是能移动的,我们把它叫做移动客户端。对于这么多端和这么多系统,我们以前比较传统的一些方案,现在都已经过时了。

所以,我们最后用 HTML5 去内嵌,跟市面上所了解的 HTML5 技术有区别的是,这里头写了 HTML5 引擎。也就是我们只是采用 HTML5 技术,但并不是采用 webview 内嵌一个 URL HTML5 的一个页。为什么这样做呢?如果我们在 webview 开一个 HTML5 页,Android 跟 HTML5 交互的时候,在 Android 或者 iOS 上,包括 Win Phone 上可能都跟传统的不太一样。所以,它的主要工作就用在 H5 的适配上面。

如果用 URL 方式打开,性能也是值得考量的。webview 开 URL 方式是请求和下载,如果这样,客户端非常卡而且不连贯,客户端不管有没有网,瞬间都能弹出来,但是用 H5 做要加载、渲染,JS 要下载,CSS 要下载,同时要绘制,这样一套时间全都省下来。

为什么采用引擎技术

引擎有版本号,每个引擎的版本号,会对应这个版本里的接口,模板。所以,老版本的情况下,可以做到版本和引擎还有模板通过配置分离,例如升级以后,如果 UI 都没有升级的情况下,在交互没有太大改变的情况下,可以同步升级。

如果我的第一版本,UI 和高版本的交互变了,增加新接口的时候,可以把这种升级脱离掉,卡掉。所以,原理来讲 Win Phone 的语言,iOS 和 Android 的编程语言都不一样,最后抽出来,编写的语法是什么?咱们可以理解成 JS,它确实是 JS 的语法。通过我们自己实现引擎技术后,大家也不用写 JS,是用 HTML5 的一个技术做的,现在除了 H5 的技术解决跨平台以外,还有一些动态加载的东西,采用动态加载的技术,这也是一个好办法,但是有很多问题。

引擎技术有这么几种问题。webview 要打开 URL,如果采用客户端,可以加载组件。如果我们只采用 HTML5 技术会比较慢,又比较卡,有明显的加载,很影响路由器的使用。如果我们做的是游戏,游戏有页游,页游一开始采用预加载的技术。但是,看一下电商,这么做肯定不行了。有关引擎的技术,我在 51CTO 上发表了引擎技术的一些文章,关于 Crow5 引擎由哪些部分组成。

移动端有哪些应用了 Crow5 这个引擎,大家可以体验一下乐蜂网。

Crow5 引擎是什么

image.png

我们现在理解的 jQuary 是一个框架,但是很显然有一些问题,例如 jQuary 负责了传统意义上 PC 网站的兼容问题。这些移动出现了类似 jQuary 的框架,比如不能动态加载,不能去加速,我还有一些模板,需要一些其他引擎。如果我们自己去做前端,很明显我们的很多引擎,很多工具,像玩塔牌游戏一样,一个一个凑起来。有了引擎和引擎,它们之间兼容性还不太好,都得依赖某一种库,有的依赖低,有的依赖高。

这时候有没有好的办法,各种组件都有了,例如 YY 等,但是国内没有利用这种引擎做移动应用。为什么?第一、太大了,加载 100M、200M 根本玩不了。第二、这些框架严重的把程序员绑架了。如果你现在采用 Jquary 的 Mobile 做一个移动端的东西,会发现它的一个理念非常好,就是 NO JavaScript Only HTML5 。里面还有一些 Bug 改起来非常麻烦,这就是为什么不采用这种框架的主要原因。还有国外的一些 only JS 也很好,但是真正国内没有应用,因为一旦用了,成本很高。

我们研究框架,研究的比较早。2011年,研究 HTML5 方向的一些框架。其实我们要做一个框架,应该具备的就是怎么样才能具备一些框架?

它应该有统一的方法论,我所要的所有的模块是具备的。至少它是可定制化的,不是绑架用户的。所以给大家看一下我们设计的框架,为什么没有去绑架用户。首先,前端技术肯定需要加载,需要异步管控,前端有一个加速器,下载器,CJS 就是一个异步。局部刷新现在也有很多种玩法,不仅仅是刷一个区域块。

现在我们做很多东西,为了提高它的效率,提倡异步去请求,请求了就请求了,回来就渲染。但是,这有一个问题,你在发一个请求的时候,它成功回掉了,如果同时发送十次,有一次比较慢,是后边把前边干掉吗?在 iPad 情况下,如果用 HTML5 做移动端会发现如果有多个选项卡,如果手速比较快,来回切换渲染同一个区间的时候,你不知道什么时候成功和失败,会对一个区域不停的渲染,数据一回来,模板加载一次,来回抖屏。如果做一个应用级的东西,这样的问题非常多,不可能所有的问题都自己写,所有的问题自己写了,你没有办法去帮助别人,让别人快速去开发。最后,我们用了一种方式,我们把程序列封装好,对外提供一个 API 去用。

image.png
乐蜂网客户端的时候,这些页面完全不是用所谓的程序自己写的,全部用引擎生成,这样的页面代码不超过 10 行,瞬间就生成了。如果以这样的东西开发 APP,其实 APP 变成像咱们以前的小积木,运营人员选几个模板,接口一抓,往上一添,APP 就做完了。

现在比这个做的还快,我们提供了一个管理平台。虽然微信自己也封装了 JSS,其实我们跟它一样,在这个 webview 我们调动了很多原生的东西,摇一摇,摇优惠券,也可以调原生的东西,这样一些活动页,都是配置文件生成的。所以如果我们采用原先的开发方式开发 APP ,天天都得更新,程序员都累死了,永无止境。现在做这个,一个大学毕业的小姑娘,教她配置两下,APP就生成了。

iPad 也是采用这样的引擎做的,iPad 有不同的选项卡,如果采用传统的 APP 配置页面,会发现模板一样,数据不一样,不停的绘制一个地方,这个问题需要一点点把它解决掉。它的原理还是采用 Native+HTML5 做移动开发,以前受限于网络和手机的性能,但是现在已经不存在了,我刚开始写手机的时候很痛苦,还有浏览器,版本 UC7.9,支持 HTML5 吗?也支持,不支持吗?确实也不太支持,当时我们做 H5 的引擎失败了,新浪投了我们很多钱,最后因为这样的问题就不投了,带着团队就走了。

Crow5 引擎具备多少组成部分


image.png


只有具备了类似的功能,把它封装好,它才可能成为咱们真正意义上的一些引擎,否则仅仅是一个工具库,例如加载器,像淘宝写的,仅仅是一个小模块。现在用统一的方法论把它组合在一起,不去绑架程序员,至少不去绑架开发。

以前我们在做乐蜂的时候,一个小截图,采用原生的方式做,审美也是一点点在进步。你会发现,随着开发我们的功能会越来越多,越来越复杂,但是开发速度会越来越快。到最后,所有的APP变得方式更多了,这样一个历程大概走了一年的时间。从引擎一个想法,到以前的一个出版,然后到一个可以商用的版本,大概走了一年的时间。现在一个稳定的版本号大概是 40 点几,也就是到 40 点几以后的版本,现在在乐蜂包括唯品会的都已经被商用掉了,现在开发到 60 多,还在继续开发。

引擎是基于约定式的开发,为什么叫基于预定呢?举个例子,如果我们的页面,叫 Index,不是特别复杂,只是一个大页,如果调用的模板叫 Index,从前端的入口到模板,再到回调函数,再到接口,都采用约定,我们在编码的时候就可以有规则。

基于这样一个想法,我们把整个的编码逻辑最后慢慢抽象出一套规则,这个有专门的文章去介绍怎么写引擎,有兴趣咱们也可以线下交流。原则很简单,一开始东西很多,慢慢抽象,抽象完了,再约定一下,约定完了,从接口到交互,到回调,到方法,全部约定,约定完了,发现代码大概少了 30%。最后我们发现,一级一级进行约定,约定完了,代码量以前有 100K,现在变成 20K,最后再对20K进行抽象,抽象出一个规则,核心的那一段处理约定的代码只有 1022 字节,还不到 1K,这个还没有压缩,压缩还能再小百分之三四十。

所以,这就是我们最后实现的情景。把约定的这套东西约定明白,完完全全可以写一个比我写的还好的引擎,这也是从一个朋友那儿得到的一个灵感。他说你要是有一个办法,让研究明白你的人花了两到三倍的时间,可以写一个更好的。基于这样一套理论,我们做了一个规则约定。我们引擎里的版本号,能够实现模板引擎、客户端的版本,三者全部漂移。这样就可以做到我们可以随便客户端和引擎的配置关系,这样方便运营,如果有问题,我们还有方案。

image.png

日志远程调试。这里还有一个特别好玩的叫日志远程调试,前端人员开发 JS 可以有一些工具,例如像 Chrome 浏览器可以调,但是做完了放到客户端里头,客户端的同学有的时候日志拿不出来,这个参数没有传,那个参数没有传,最后我们自己做了一套在客户端也可以看日志的东西。还有心跳保持,从青蛙的身上发现了一些好的东西启发到我们。

例如我们在秒杀的时候,如果邻近这个秒杀点的时候,我们的 APP 自己会有一个服务器的心跳,会看库存,看时间开始,邻近秒杀的时候,会自动的心跳加速,比如以前 10 秒请求一次,邻近那个点,可以变成 1 秒请求一次,超过这个点,可以 10 秒请求一次,随着你的心跳,请求可以变快或者变慢。还有万一进入一个地方,信号变弱了,两次请求不到的时候,心跳会进入休眠模式,睡觉了,什么时候启动呢?当时设想,自己也想了很多种策略,发现大部分人身上有很多奥秘,像青蛙。

最后我们发现什么时候启动这个心跳是比较合适的时期呢?当用户再去点击任何一个按纽的时候,如果这个时候还没有请求到网络,说明现在还没有信号,不用去让引擎自己去启动这个心跳,当你再点击到一个按纽,从网上请求数据的时候,你发现网络已经通了,心跳保持器从冬眠的状态到开始加速就可以了。类似这样的机制,在引擎里面,全部都提供了这种封装。咱们也涉及到一些安全性的问题,前面有很多过滤器,有一些比较讨厌,抓你的包,给你注入点东西,所以这里还有一些前端安全的过滤的东西。

如果我们现在做了一个 APP,使用 H5+Native,测试人员测试 APP 的时候,看不到所有调试的代码。但是,现在我们的引擎可以把调试代码通过服务器存到一台 PC 机上,你可以通过 PC 机操作 APP,如果里面是 H5 做的,H5 所有都会输出,但是这个箭头是双向的,就是除了可以把日志显示在 PC 机,同时,所改即所见,你写的代码立刻就在那儿反映。所以可以直接调试手机,这样在测试的时候会极大的方便我们。

image.png
布局管理器。Criteria 采用方格的形式,把一个页面分隔成多少方格,其实做的比它更灵活,还是基于模板。为什么?因为我们觉得基于方格的方式不太响应中国人的思想,外国人做的东西格式良好,方方正正,中国人做的是波浪形式的。所以,我们感觉还是基于模板做响应式的工具比较好。

我们基于 HTML5 的技术并没有真正的使用 HTML5 原生的东西,而是全部用客户端翻译了一遍。我们在客户端离线存储,所有的机制都是用客户端自己实现的,自己实现的东西可以控制,大小也可以控制,功能也可以控制,加密解密也可以控制,图片压缩也可以控制。我们在浏览器内部做了一层代理,如果用 H5 的技术去做,走的是 webview,但是我们直接把请求发给客户端,由客户端代理服务器,这样客户端可以做缓存、加密、解密,还有解压等等操作。

image.png
心跳加速。写这个东西的时候,不是写代码,而是给它一个配置文件,一个引擎,引擎自动把它渲染出来。渲染出来以后,心跳的起搏器去取数据,然后去比较。比较以后,本地有一个数据驱动,数据驱动不是像阿贾克斯,去服务器取 200K 的数据,取回来渲染,这是现在比较主流大家常用的。

但是我们现在不这么做,其实很多时候取数据,100K 和 200K 里面可能有 80K、90K 的东西不一样,所以现在一个原理,请求完数据会跟本地的数据进行一个比对。就是我虽然请求了一次阿贾克斯,但是最终渲染的时候不是渲染大区块,是渲染一个 iterm。它的力度要比咱们说的阿贾克斯的方式更加精确。所以,体验上会更快。没有办法给大家演示一些我们做的小 DAO,即使按浏览器的刷新键,所有东西全部干掉,重新加载,但是采用引擎技术,技术刷新,页面的东西瞬间出来了,没有明显的等待。

跟客户端原理一样,在没有请求数据之前,我们所有的模板事先加载出来了,如果采用引擎去做,页面即使没有请求数据,格子、框架全部应该出来了,所有东西都有。什么时候去渲染数据呢?这个时候我们会有心跳起搏器去自动的服务器请求数据,数据会和本地的模板数据进行比对,如果发现两次的数据不一样,由数据把模板驱动一下,把数据添到咱们指定的块里,像填空题一样。所以,我们发现可以用 HTML5 技术做的更好。请求完数据,也不会一次性刷新,会把数据添进去,用户感觉这个东西非常的连贯。

引擎的设计模式

image.png
现在框架基本上都是 MVC 的,一个控制器,一个服务,然后渲染一个模板,填充一个数据层,DAO。刚才看到那么多种组建、模式全部都是插件,引擎是核心,也只是给一个配置文件,程序由这个东西自动写。

我觉得这样的方式还是比较慢。所以,干脆做了一个东西,Main,然后接口文档里面,附带了一个接口的数据格式,数据格式就是我刚才说的 data,静态填充的数据格式是什么?所以,基本上我们这个 APP 开发变成了一个配置。但是,最后发现这个管理平台还是比较慢,虽然配置文件不行,管理平台最后又发明了一些命令行工具,程序员想写这样一个 APP 很简单,就敲一下,做电商,做社交,最后加载资源,弹出一个资源,一点到配置平台,最后 APP 做完了,这是现在我们的开发模式,基于一个引擎怎么去开发一个 APP。

今天的分享到此结束,谢谢大家!


又拍云 Open Talk 是由又拍云发起的系列主题分享沙龙。秉承又拍云帮助企业提升发展速度的初衷,又拍云 Open Talk 将用全干货的形态,为互联网从业人员呈现以技术为主,同时涵盖产品、营销、融资等各个方面的专业知识,帮助企业成员不断的提升自身专业技能,以推动企业更快的发展。