Mocha: 58同城 App 基于卡片的线上 AB 测(线上卡片动态换)
目录:
- 1. 需求背景
- 2. 客户端设计
- 3. Server 端设计
- 4. demo 效果
1. 背景
基于卡片的线上 AB 测能力作为 58APP Android 端 Wafers 系列工作的一部分。在此项目之前,Wafers 已经在 58App 端完成以下工作:
1. 提升本地编译速度 70%
2. 减小包大小和动态化,实现业务提效,包括:招聘页面动态化,减少由于 DU 框架带来的 6M 包大小
3. 推广包大小减少 30% 以上,实现渠道转换率提升 15%
4. 业务模块动态化,实现厂商基础包未删减功能的前提下,包大小减少 50M,减少 49.8%
5. 任意门:实现了基于页面级别的线上 A/B 测,bug 修复,紧急需求上线的能力;招聘、部落已接入并使用其上线多个需求,
最高日更新生效设备 178万
重点介绍一下任意门:
- 基于 Wafers 实现, 动态更新不能修改底层库、通用 SDK 配置等
- 基于 App 版本级别,更新只会对某个特定 App 版本生效,如果需要覆盖多个 App 版本,则需要上线多次
- 静默下载更新,对用户无感知
- 基于页面级别的路由替换
但是有一个问题,局部元素(UI+逻辑)如何实现线上A/B测?
由于 58App 首页由无线组维护,首页是用户冷启动后就会进入的页面,且首页的落地页代码非常复杂,难以实现动态路由替换落地。而我们收集了产品方面的线上 A/B 测需求,发现有比较大一部分是基于卡片的 A/B 测:
方案讨论:
# | 方案 | 结论 |
---|---|---|
1 | 任意门 | 只能实现页面级别的路由替换,无法实现局部元素的替换 |
2 | 动态化布局 DSL | 如 Tangram 是基于组件的布局动态化,不仅无法实现逻辑动态化,且对现有逻辑有比较大的改造成本 |
3 | RN/Flutter | 首页是核心页面,为了稳定性和体验,所以没有采用 RN/H5/Flutter;同时 58App 需要做 A/B 测的其他页面大部分是 native,改造成 RN/Flutter 难度大 |
4 | 基于 Wafers 动态更新 + 任意门的包下发更新逻辑,实现基于卡片的线上 A/B 测能力 | 可行,基于任意门的卡片动态化,是追求最低侵入式的实现。动态包更新范围和任意门一致 |
适用范围:
可用于以下卡片的线上 A/B 测、bug 修复、上线时效性很强的线上运营需求等,实现 UI + 逻辑维度的动态更新:
- 首页卡片(如九宫格卡片、推荐卡片、个人中心卡片)
- 微聊卡片
- 列表卡片 (首页 feed 流、其他列表)
- 普通卡片
2. 客户端设计
Mocha(Mókǎ, 摩卡,谐音魔卡)
任意门是提供基于 Activity 级别的路由替换,Mocha 作为任意门的一个新分支,目标是实现普通卡片、列表卡片的线上 AB 测,bug 修复及强运营活动的能力。
设计核心:
- Mocha 注册的模版不区分业务线,无需受制于任何业务接口/基类。type 是一个模版的唯一标识,只要列表接入了 mocha 能力,server 列表数据中下发的 type 为该 type 时,即可正常渲染加载该卡片。
- 对 server 数据结构侵入小,以新增数据的方式进行处理。
- 方便动态包的业务集成到主分支:只需要将动态包业务代码直接移动过去,并在基础包中注册该卡片即可 (相当于基础包内置了该卡片)。
3. Server 端设计
设计要点:
- 在老接口上扩展
- 区分 App 版本号
- 通过 AB 测平台分流
接下来我们来看下具体的协议设计。
普通卡片
以首页六宫格推荐卡片为例,我们在 AB 测时保留原有的数据,使用扩展的方式来实现,此时分成两种 case:
(1) case 1:新卡片的数据复用旧卡片的数据
这种 case 占到 90% 以上,一般产品对于 AB 测的诉求是修改 UI 样式/体验,这时协议如下。
旧协议:
{"section_recommend_new": [{"icon": "https://j1.58cdn.com.cn/arthurupload/zhiyou/mrs/ershoufangpic.png","subtitle": "特价二手房","title": "北京"}, {"icon": "https://a.58cdn.com.cn/app58/icons/homepage_lgg_zp00004.png","subtitle": "免费提供住宿","title": "教师/助教"}, {"icon": "https://pic8.58cdn.com.cn/nowater/tribenowatermark/n_v2c73eb7192e1d4148bb1c61c09c7f0e4f.png","subtitle": "都是仓储人哦","title": "仓储管理员"}, {"icon": "https://pic6.58cdn.com.cn/nowater/tribenowatermark/n_v2eeed9f9527fa47229bfee4356d505151.png","subtitle": "你是哪个厂的","title": "普工大家庭"}, {"icon": "https://pic1.58cdn.com.cn/nowater/tribenowatermark/n_v2c603c91b33d049ac9e0317f25a2d1359.png","subtitle": "烫染洗剪吹喽","title": "美容美发圈"}, {"icon": "https://pic7.58cdn.com.cn/nowater/tribenowatermark/n_v25d526b020b5a48f0b67e83cad86d9b65.png","subtitle": "北京人一起聊","title": "北京人"}]
}
新协议:
增加一个字段,key 为动态包中新注册的卡片 type, value 为 {} / [],这时旧卡片将用新卡片的样式、解析器来解析渲染,此时使用的数据仍是旧卡片的数据。
{"mocha_recommend": [],"section_recommend_new": [{"icon": "https://j1.58cdn.com.cn/arthurupload/zhiyou/mrs/ershoufangpic.png","subtitle": "特价二手房","title": "北京"}, {"icon": "https://a.58cdn.com.cn/app58/icons/homepage_lgg_zp00004.png","subtitle": "免费提供住宿","title": "教师/助教"}, {"icon": "https://pic8.58cdn.com.cn/nowater/tribenowatermark/n_v2c73eb7192e1d4148bb1c61c09c7f0e4f.png","subtitle": "都是仓储人哦","title": "仓储管理员"}, {"icon": "https://pic6.58cdn.com.cn/nowater/tribenowatermark/n_v2eeed9f9527fa47229bfee4356d505151.png","subtitle": "你是哪个厂的","title": "普工大家庭"}, {"icon": "https://pic1.58cdn.com.cn/nowater/tribenowatermark/n_v2c603c91b33d049ac9e0317f25a2d1359.png","subtitle": "烫染洗剪吹喽","title": "美容美发圈"}, {"icon": "https://pic7.58cdn.com.cn/nowater/tribenowatermark/n_v25d526b020b5a48f0b67e83cad86d9b65.png","subtitle": "北京人一起聊","title": "北京人"}]
}(2) case 2:新卡片的数据需要新数据由于一般卡片的数据来自于各业务线,所以新卡片需要新数据时,需要和业务线配合一起开发新数据的 AB 测,数据仍是存放在新增的字段值中。旧协议:{"section_recommend_new": [{"icon": "https://j1.58cdn.com.cn/arthurupload/zhiyou/mrs/ershoufangpic.png","subtitle": "特价二手房","title": "北京"}, {"icon": "https://a.58cdn.com.cn/app58/icons/homepage_lgg_zp00004.png","subtitle": "免费提供住宿","title": "教师/助教"}, {"icon": "https://pic8.58cdn.com.cn/nowater/tribenowatermark/n_v2c73eb7192e1d4148bb1c61c09c7f0e4f.png","subtitle": "都是仓储人哦","title": "仓储管理员"}, {"icon": "https://pic6.58cdn.com.cn/nowater/tribenowatermark/n_v2eeed9f9527fa47229bfee4356d505151.png","subtitle": "你是哪个厂的","title": "普工大家庭"}, {"icon": "https://pic1.58cdn.com.cn/nowater/tribenowatermark/n_v2c603c91b33d049ac9e0317f25a2d1359.png","subtitle": "烫染洗剪吹喽","title": "美容美发圈"}, {"icon": "https://pic7.58cdn.com.cn/nowater/tribenowatermark/n_v25d526b020b5a48f0b67e83cad86d9b65.png","subtitle": "北京人一起聊","title": "北京人"}]
}
新协议:
增加一个字段,key 为动态包中新注册的卡片 type, value 为需要的新数据,这时旧卡片将用新卡片的样式、解析器来解析渲染,此时使用的数据是新卡片的数据。
{"mocha_recommend": [{//...},{//...},//...],"section_recommend_new": [{"icon": "https://j1.58cdn.com.cn/arthurupload/zhiyou/mrs/ershoufangpic.png","subtitle": "特价二手房","title": "北京"}, {"icon": "https://a.58cdn.com.cn/app58/icons/homepage_lgg_zp00004.png","subtitle": "免费提供住宿","title": "教师/助教"}, {"icon": "https://pic8.58cdn.com.cn/nowater/tribenowatermark/n_v2c73eb7192e1d4148bb1c61c09c7f0e4f.png","subtitle": "都是仓储人哦","title": "仓储管理员"}, {"icon": "https://pic6.58cdn.com.cn/nowater/tribenowatermark/n_v2eeed9f9527fa47229bfee4356d505151.png","subtitle": "你是哪个厂的","title": "普工大家庭"}, {"icon": "https://pic1.58cdn.com.cn/nowater/tribenowatermark/n_v2c603c91b33d049ac9e0317f25a2d1359.png","subtitle": "烫染洗剪吹喽","title": "美容美发圈"}, {"icon": "https://pic7.58cdn.com.cn/nowater/tribenowatermark/n_v25d526b020b5a48f0b67e83cad86d9b65.png","subtitle": "北京人一起聊","title": "北京人"}]
}
{"msg": "success","code": 580200,"list": [{"type": "business_onepic","infoId": 1219500454809636864,"commentNum": "17",...},...]
}
AB 测时,需要将 business_onepic 卡片改成 mocha_ business_onepic 卡片做测试,那么新协议为:
分组分流时,对于命中的用户,不会下发 business_onepic 的数据,而会下发新的卡片 mocha_ business_onepic 的数据。
{"msg": "success","code": 580200,"list": [ {"type": "mocha_ business_onepic","mocha_pic": "...","mocha_url": "...",...},...]
}
4. demo 效果
https://wos.58cdn.com.cn/IjGfEdCbIlr/ishare/video_Xd59d1XdWbd3d37bWcU5XU7bd1U7d3Xd.mp4
Mocha: 58同城 App 基于卡片的线上 AB 测(线上卡片动态换)相关推荐
- 基于 React Native 的 58 同城 App 开发实践
作者简介: 彭飞,58 同城 iOS 客户端架构师.专注于新技术的研发,主要负责 App 端组件化架构以及性能优化,并已推广 React Native 在 58 同城 App 中业务场景的应用.在 M ...
- Android进阶之路 - 实现58同城APP加载中页面
此文引用的是58同城的加载动画,虽然出来有一些年头了,但我表示使用的时候因技术原因我还是遇到了一些或大或小的坑. 转载请注明:http://blog.csdn.net/qq_20451879/arti ...
- 58 同城 Android 端 HTTPS 实践之旅
自 WWDC 2016 苹果传递出从 2017 年 1 月起强制启用应用程序安全传输协议(App Transport Security)的信号,各大厂均开始了 HTTPS 化的征程.虽然目前苹果将此计 ...
- 分享篇 - 58同城基于Android APP Bundle开发的全新编译模式(编译速度提升70%)
目录 1. Wafers 项目背景 2. 效果展示 3. 实现方案 4. 改造期间遇到的问题 5. 如何接入使用 6. 对比 Instant Run 和 Apply Changes 7. 总结 1. ...
- 产品设计:58同城与赶集网APP改版建议
2015年年底,作为一岁的产品经理,收到了大神的面试邀请,来到了58赶集面试产品狗. 虽然业务部门的面试均已通过,无奈最后面试卡在了只跟我聊了5分钟然后就赶去吃饭的HR上.也因此失去了很多宝贵的面试机 ...
- 58同城首页腰部动态化技术选型(布局动态化)
1. 行业情况 1.1 基本概念介绍 1.1.1 Web混合 Web 前端和客户端的混合开发.使用 WebView 进行页面渲染.逻辑执行:依赖客户端的能力需要通过 JSBridge(通信桥) 的方式 ...
- 58同城智能推荐系统的演进与实践(转)
58同城作为中国最大的分类信息网站,向用户提供找房子.找工作.二手车和黄页等多种生活信息.在这样的场景下,推荐系统能够帮助用户发现对自己有价值的信息,提升用户体验,本文将介绍58同城智能推荐系统的技术 ...
- 58 同城 iOS 客户端 IM 系统演变历程
[编者按]58 同城 App 自 1.0 版本开始,便一直致力于自研 IM 系统.在这过程中,发现如何降低 IM 系统层次和页面间的耦合,减少 IM 系统的复杂性,是降低技术成本提高研发效率的关键.对 ...
- 58同城Android端-最小插件化框架实战和原理分析
目录 背景 插件化需要了解的知识 2.1 类加载过程和类加载器 2.2 ClassLoader 的 findClass.findLibrary.findResource 2.3 DexClassLoa ...
- 58 同城 iOS 客户端组件体积分析与统计实践
[导读]目前 58 旗下存在租房.安居客.招聘.二手车.黄页等多个业务线,其中每个业务线在 58 APP 中存在一个或多个业务 pod.在研发层面上,58 同城其实早已实现了并行研发,不过,在并行研发 ...
最新文章
- 最年轻院士入职浙大,近两年浙大引进45位高层次人才~
- 2013年上半年全国高等学校(安徽考区)计算机水平考试试卷,2013年上半年全国高等学校(安徽考区)计算机水平考试试卷(6页)-原创力文档...
- Android Hal层简要分析
- Spring for Android 1.0.0发布
- 剑指 Offer 07. 重建二叉树【千字分析,三种方法】
- 剥开比原看代码(八):比原的Dashboard是怎么做出来的?
- Java之jdk和CGLib实现动态代理
- NativeScript - JS 构建跨平台的原生 APP
- qt没有mysql文件夹_qt5-qt目录下没有mysql文件夹
- 图像目标检测(Object Detection)原理与实现(一)
- mysql设置用户永不过期_在Navicat Premium中管理MySQL用户 - 第2部分:创建新用户
- 安装 RabbitMQ
- Android 开机logo支持的格式
- ElasticSearch SQL 日期函数
- java中观察者模式的使用场景
- 常用三种正态检验方法
- 移动通信基础(8)帧结构
- 计算机屏幕闪烁黑屏,台式机电脑。显示屏指示灯一直闪烁,屏幕黑屏。。...-显示器电源灯闪黑屏...
- sqoop export hive数据同步到oracle的用法
- 日语自学学习网站汇总