利用Poplayer在手淘中实现稳定业务和临时业务分离

云栖TechDay活动第十四期中,来自阿里的云魂给大家带来了题为《Poplayer》的分享,分享中他重点介绍了手机淘宝在分离稳定业务和临时业务所做的一些尝试和探索。

下面是现场分享观点整理。


如何分离稳定业务与临时业务?

如何才能分离稳定业务和临时业务?我们在回答这个问题之前,首先要搞清楚什么是稳定业务?什么是临时业务?

利用Poplayer在手淘中实现稳定业务和临时业务分离

图一 如何分离稳定业务与临时业务

对于电商应用而言,例如我们用手机淘宝浏览某一款宝贝时,在详情页面将其添加到购物车,再去购物车结帐,整个交易流程是非常稳定的,因此这些详情页面可称为非常稳定的业务。在详情页面上,交易转化率会非常高,因为用户来到详情页面时,基本上他交易的可能性就非常大;如果他只是在什么淘宝头条看一看,他的目的可能并不是说看宝贝,有可能只是看一看资讯之类的,这样情况下交易转化率不是很高。

所以对于上述详情页面的例子,就可以定义为稳定的业务。稳定就意味着在这上面的代码不能够随意乱改,因为随便乱改有可能会增加非稳定性。

什么叫做临时业务? 对于电商应用而言,会面临很多节日或者大型促销活动。这些促销活动的代码是不大可能去复用的,比如说今年的双11我们有这样的玩法,明年双11可能又会其他的玩法,这种业务相对非常临时,而且基本上也是属于脑动大开的设计,它不会像详情页具有固定的模式。

明白稳定业务和临时业务的概念后,我们要看一下为什么要去解耦它们两个之间的关系:一方面是稳定性,比如说我今天要在详情页面去做一个大型的促销活动,直接去乱改详情页的代码,做完促销活动,再把原来的代码恢复出来。这样为了特定的活动而反复修改代码将会导致它的稳定性非常之低,哪怕出现一丁点差错也会引起交易量的下跌;第二个原因与发版节奏相关,在一款电商应用中,临时业务和稳定业务开发基本上属于常态化的一种现象。稳定的产品,它有固定的节奏,比如说这一周我们应该添加某项功能,下一周应该添加另一项功能,产品自身具有这样一种节奏;但是临时业务正如我刚刚介绍那样,它的计划性不像产品的节奏那样稳定,极有可能是下周进行一个促销,这周需要加班进行研发,整体的发版节奏就很成问题。活动开发有活动开发的节奏,产品开发有产品开发的节奏。

Poplayer的起源

利用Poplayer在手淘中实现稳定业务和临时业务分离

图二 Poplayer的起源

手淘在解耦两者之间的关系的过程中做了非常多的探索。从2014年双11开始,基本上采取是Native开发。比如说双11我们要去做一个活动,可能我们会在提前一两个月,Native的同学就开始去做开发。2015年的双11又换一种新的活动玩法,这些代码就完全废掉了,对于此次活动而言,两者之间是完全没有解耦的。从2014年双十二开始,我们尝试了Hybrid的方式,比如说今天想在一个详情页去做一个活动,我们可能会在详情页嵌入一个Webview,需要进行活动时,直接调用Webview,在其上写一些相对应的前端代码即可。

实际上,这种做法是存在弊端的:一方面,单纯地搭建Webview时,会导致下层页面的隔离特别大,活动的板块会覆盖大部分的详情页面,用户体验不是太好;另一方面,这种做法并没有解决所有页面的问题,例如你可能在详情页需要嵌这样一个Webview,在首页又想做这样一个活动,就需要在首页上再嵌入一个Webview,它没有一套统一的管理机制。

经过持续探索之后,我们开发了一款名为Poplayer的中间件,专门用于支持活动营销和非稳定业务与稳定业务隔离。 它主要采用的是AOP方式,在每次页面切换的时,将Webview嵌入到对方页面当中。所以说对于详情页开发的同学,其实他并不知道详情页上已经嵌入了Webview;同样地,首页的开发同学也不知道在首页上也已经嵌入了Webview。这样做一方面在代码上实现了解耦;另一方面提供了统一的机制,多页面嵌入Webview时,无需分离开来,所有的场景实现了一次投入重复使用。对于Poplayer而言,它对事件的分发做了一些处理,在容器层做了一些事件处理流程的改变,对弹出的页面进行了优化,提高了整体的用户体验。

总结来说:PopLayer是一个可以在任意Native页面(这个页面甚至可以是Browser)弹出H5的部署容器,可以在无需发版的情况下对已有的Native界面上浮出透明浮层,并且可以不影响Native页面本身的交互。PopLayer技术最重要的意义就是:在同一页面上分离稳定产品与临时业务。

下面来看一些PopLayer的Showcase。

利用Poplayer在手淘中实现稳定业务和临时业务分离

图三 PopLayer在手淘中的应用

上面的这三个图是手淘中的三个产品,对应于程序而言,它其实就是三个模块。在这三个图中红色线条框内的就是PopLayer,包括独占式和非独占式两类,形态多种多样,因此用户其实是感知不到三者是一个统一的解决方案。

利用Poplayer在手淘中实现稳定业务和临时业务分离

图四 利用PopLayer产生的搜索特效

在双十一活动时,它还做出来了上图所示的效果,即在搜索页面产生一些特效:例如,搜索肥皂、冰箱等关键词,会弹出一些彩蛋以及气泡等特效。

后续,我们还在双十二年货、手机淘宝发红包等活动中使用了PopLayer,用于营造活动氛围。此外,PopLayer除了用于做活动之外,还会用它来做一些新产品的试水,例如淘宝中“问大家”产品中就是利用PopLayer开发的。如果产品不成功,就可以直接将该配置切掉,对于详情页而言,代码不发生任何变动。

PopLayer在双11中的应用

下面我就介绍一下PopLayer在双11中的一些应用。

利用Poplayer在手淘中实现稳定业务和临时业务分离

图五 PopLayer在双十一的应用

在左边的计划内和右边计划外的各自包含了一个PopLayer使用的案例。计划内使用是指双11之前就已经确定了这些活动,投入开发,创造可能;计划外使用是指在双11之前是没有想到此类情况的发生,需要临时增加的活动以解决当时产品上的问题,从而增加的一些额外使用。

创造可能

利用Poplayer在手淘中实现稳定业务和临时业务分离

图六 利用PopLayer实现搜索特效

上图所示就是计划内的创造可能,这里以搜索关键字(包括气泡、裂屏等关键字特效和红包密令)为例对创造可能进行讲解。在阿里电商应用中,尤其像双十一这类非常大型的活动当中,我们开展活动极有可能手机淘宝、手机天猫、聚划算等众多应用上同时进行进行,而非单独各自开展。例如搜索关键字,不管在天猫,还是在手淘中去搜索,都会出现特效关键字或者红包密令。但是这意味着我们需要在淘宝iOS、安卓、iPad和天猫iOS、安卓、iPad共6个客户端上都需要做同样的控件;另外整场活动需要涉及到4个页面,如果完全采用Native思维,这个工作量还是挺大的。

目前,搜索红包采用的是PopLayer的设计流程,在搜索框中,输入关键词后点击搜索按钮时,会将PopLayer(上图所示的黄色中转页)给拉起来,对于用户而言,它现在是不可见的,它完全是一个透明的东西,可以把它理解作执行一段JS逻辑的引擎。由它来决定用户所输入的关键词是否应该出现关键词特效或者红包密令,亦或是正常搜索结果。

如果要出现关键字红包,是在客户观看完弹出的关键词特效之后,自动出现小红包,点击红包就会跳到对应的商铺页面,出现抽红包的活动页;另外要弹出红包密令时,它首先要判断输入的关键词是否要弹出红包,然后再进行红包弹出操作。这种做法的优势在于:由于H5本身就是跨平台的,前端只要写这样一份代码就能通过PopLayer这个调度框架实现在6个客户端上运行。

急速交付

利用Poplayer在手淘中实现稳定业务和临时业务分离

图七 PopLayer在计划外的使用

下面再来看一下计划外的急速交付,上图中标出了几个时间点,是指在双十一中计划之外的活动,根据当时的状况判断是否需要增添新的促销手段和额外的活动。我们开发的速度是非常快的,例如双十一当天,首页有一个“再来一波”的引流,需要给用户发更大量的红包,进而刺激交易量,我们开发这个活动仅仅花了24个小时。整个双十一中,临时活动中的75%的活动是在两小时以内开发出来的。

此外,由于H5在出问题后可以及时地进行修改代码,立马生效。因此在临时活动中,没有出现BUG,即使出现了,在几分钟内也可以解决。

PopLayer的应用场景

利用Poplayer在手淘中实现稳定业务和临时业务分离

图八 PopLayer的应用场景

PopLayer的应用场景上文也有讲到:它支持自定义的定投,由于PopLayer全透明时用户完全无感知,所以天生可以完成任意逻辑的定投,例如通过PopLayer区分新老用户来进行投放不同的大礼包活动;另外它支持混合开发,由Native完成稳定的功能,由PopLayer完成多变的业务,比如春节的打年兽活动,通过与Native页面产生一些交互,让用户认为是首页开发的一个活动;最后,它支持复杂交互,临时入口可以有交互逻辑。

PopLayer的设计

利用Poplayer在手淘中实现稳定业务和临时业务分离

图九 PopLayer的工作流程

上面我们所提到的都是它在业务上的价值,这里我们从技术上看一下它的整体设计过程。上图是简化框架图,表示的是它的工作流程:页面切换时(从首页跳到详情页,这样的动作定义为一次页面切换),去远端读取配置,判定对应的切换是否需要弹出PopLayer,如果不需要,则正常的跳转过去;如果需要弹出PopLayer,则将对应的Webview加载到Native页面上。当然这里面还存在另外一个逻辑,当用户的点击事件到来时,我们会根据他点击的像素点的透明值的分量,与对应的阈值去做判断,如果超过了阀值,无需拦截它,直接交给H5处理,用户就点击到H5上的元素;如果没有超过这个阈值,则将此次事件拦截放弃处理,将该事件交给下层的Native页面做相对应的逻辑。

利用Poplayer在手淘中实现稳定业务和临时业务分离

图十 PopLayer的静态模块

上图是从相对静态、模块化的角度去分析PopLayer的不同模块。对于上文提到触发时机,PopLayer不但支持页面切换触发,也会支持用户自定义发送的消息触发。在生命周期模块,主要包括消息管理、配置管理以及规则管理。PopLayer View模块中,最重要的是做了点透处理的逻辑,就是用户点击到了透明的地方,能够把事件给放行下去,非透明的地方还是交给H5去处理;另外通过页面加载保障了Webview 的完全加载;此外还提供了jsbridge API,通过更为安全的逻辑来保证其可以调用Native的接口形成互动。

由于PopLayer不仅在手淘中应用,同时它还提供给天猫、聚划算等应用。不同的应用的各自配置推送、页面导航等细节的处理不同,因此,PopLayer提供了一个系统调度的界面,内部实现时,各个接入方遵守这一套规范。图中最左边的开发调试工具模块也十分重要,这是因为PopLayer的开发涉及Native、 iOS和安卓以及前端开发联调。通过对开发调试模块进行优化,不仅加快了问题排查速度,同时也与PopLayer主打的急速交付目标相符。

PopLayer的核心技术点

利用Poplayer在手淘中实现稳定业务和临时业务分离

图十一 PopLayer的核心技术点

PopLayer的核心技术点在上文中也有涉及,这里在进行总结一下:第一点就是点透能力,对于iOS主要采用了CGBitmapContextCreate和hitTest(对于Android主要采用了View.getDrawingCache()和onInterceptTouchEvent)去处理点透事件的流程,通过获取当前的点击位置的RGBA值,根据透明度判断是否要在当前webview处理,或是跳过当前webview。

第二点是健壮性保障,前端在使用jsbridge调用display接口后才会真正展示PopLayer,保证了整个webview显示的完整性。

第三点是可扩展性保障,消息方面,双十一期间增加了timer、自定义消息、PopLayer协议三种方式;前端方面定义了大量jsbridge API,满足各种需求。

上一篇:实战营第三期:MySQL数据库进阶实战


下一篇:Algorithm-线性dp-leetcode-300. 最长递增子序列