关于前端AB实验,我是这么思考的

简介: 背景大家好, 我是Fly哥, 这次分享的内容主要是关于ABtest ,我们是做用户增长的,说白了就是对应下面几个关键词。拉新、激活、留存,留存的话 又分为 次日留存、 3日留存,这些都是我们的指标, 但是产品设计一个需求的时候, 可能会有实验的性质,不确定哪一组实验,对于指标的反馈是正向的,或者是那一组实验的效果更加明显。 这时候产品就会去创建AB实验,然后拿线上的一部分流量,去做实验, 分析数据, 得出实验结论,然后看是否满足预期, 如果不满足 就暂停实验, 或者进行全量实验。 大家可以看下下面这张流程图:图片然后对于我们前端而言,我们关心的点只有两个第一个就是接入ABtest,

背景



大家好, 我是Fly哥, 这次分享的内容主要是关于ABtest ,我们是做用户增长的,说白了就是对应下面几个关键词。拉新、激活、留存,留存的话 又分为 次日留存、 3日留存,这些都是我们的指标, 但是产品设计一个需求的时候, 可能会有实验的性质,不确定哪一组实验,对于指标的反馈是正向的,或者是那一组实验的效果更加明显。 这时候产品就会去创建AB实验,然后拿线上的一部分流量,去做实验, 分析数据, 得出实验结论,然后看是否满足预期, 如果不满足 就暂停实验, 或者进行全量实验。 大家可以看下下面这张流程图:


image.png


然后对于我们前端而言,我们关心的点只有两个


  1. 第一个就是接入ABtest,然后去做逻辑处理, 根据当前用户命中的不同实验,走不同的逻辑


  1. 第二个就是实验结束后的操作,不管是应用实验 还是 暂停实验, 那么对于我们而言都是进行代码删除


ab实验是什么??


可能很多同学讲到这里还是有点模糊,我在这里举一个最简单的例子, 我们在实际开发过程中的


我们通常在页面有样式变化,但又不确定是修改影响好坏的时候进行 AB 实验,实验数据可以为改版提供有力支持。

某公司日常(1)产品:把页面标题变成之前的两倍。标题就是要醒目,要大大大

image.png

image-20220604101406387


设计:打死都不同意,太大的标题不精致不优雅。 BOSS:下面的按钮点击导流就是收入。收入就是一切!!!你们做下实验,采用收入高的方案。 前端:哦。


从上面的图片 可以看出, 其实我们采取了AB 实验, 对于不同的用户,页面可能展示 不一样, 其实就是选取线上一部分流量,去进行实验, 然后划定目标人群, 对比数据的变化, 最终采取是否运用。


如何接入ABtest



我们先看下第一个问题, 前端如何ABTest。 我们看下老的接入AB流程图, 基本上是 产品创建一个AB 实验, 后端同学就要写一个接口, 我们去调用。 然后得到的该用户命中的分组信息,然后我们在根据逻辑判定。 如下图:


image.pngabtest1.


通过与产品交流得知, 目前得物的AB 实验平台分为下面三种


  1. 客户端实验


  1. 后端实验


  1. H5实验


用户的分组信息, 以及实验的名称都是产品在 AB 实验平台进行创建的,产品会在prd上


写上, 如:


key: 'xxxx',
value: 'old' 对照组
value: 'new1' 实验组1
value: 'new2' 实验组2


而后端获取用户AB信息 也是AB平台提供的分流接口, 然后在转发给我们, 所以后端接口起到了一层中间层,那就没必要了,这个链路是可以优化的,我们可以在创建实验的时候,拉上产品和后端同学进行沟通, 确认你是不是需要用户AB的信息,进行逻辑处理,如果完全不需要的。那么产品创建的时候,就创建H5 实验, 然后我们就直接调用AB 平台提供的H5接口,获取AB 信息就可以了。 如图所示 :

image.png


一个实验倒还好, 但是如果有很多实验, 并且对应的是不同的业务, 所以没办法保证每个开发接口的同学,保证接口的返回值统一,有的返回一个布尔值, 有的返回字符串。 但是这部分逻辑就是通用的,所以当后端不需要拿到用户的AB 信息,去对不同的用户 做逻辑处理的话, 我们就可以不走他们接口,将这部分逻辑统一封装到sdk 中,方便各个业务线调用,专注业务开发,不需要关心用户的分组信息


image.png


当时这么设计的原因主要有下面几点: 因为团队的技术栈有laya, cocos, react,他们在渲染层的处理方式都不一样, 所以分了两个npm包一个负责逻辑处理,一个负责渲染层, 做到解耦。 因为AB 平台后续会支持H5实验,传入 多个key ,得到当前用户在多组实验对应的分组信息,所以对应的设计图如下:

image.png

代码删除

谈到做AB 实验, 我拿我目前负责的一款游戏点鞋成金举例子: 产品要对游戏的头部进行做实验,看是不是直接凸出奖励,对于用户的吸引力更大

分别对应3个组 第一个是对照组

image.png

第二个是实验组1

image.png

第三个是实验组2:

image.png

如果要要去开发的话其实就会这么去写:


if (info === 'A') {
  // 实验A 用户的展示逻辑
} else if (info === 'B') {
  // 实验B  用户的展示逻辑
}else if(info === 'C') {
  // 实验C 用户的展示逻辑
}


其实看上去还好对吧, 不就是多写几个 if else  , 但是你 随着产品的实验 越来越多, 你这样的代码会越来越多。 会带来下面这 几个问题


  1. 当实验全部应用一个 数据比较好的 情况下, 你的那些脏代码,是不是要全部删除。这个需要我们前端 还要 花时间 去定时清理


  1. 因为虽然你可能只是删除了代码,在上线的时候其实也需要测试  进行回归, 万一你误删了,可能你和测试都不知道,造成线上事故


  1. 这两者 其实都 占用了 开发 和测试的一些时间  ,怎么做到提高代码的可维护性和稳定性呢

cocos


这里我介绍下cocos 方面我是怎么处理的, 用cocos 做的游戏, 页面每一个元素都叫做一个node ,每个节点上都有一些基础的属性,比如设置节点的 大小, 缩放, 锚点,还包括绑定脚本,绑定各种各样的组件 等等。如图所示:


image.png

其实我们可以开发一个自定义AB组件, 然后在脚本设置可以在编辑器中使用, 这样每个节点就可以添加到我们自定义的脚本组件。

// 编辑器特性
    editor: {
        // 允许当前组件在编辑器模式下运行
        executeInEditMode: false,
        // 当本组件添加到节点上后,禁止同类型(含子类)的组件再添加到同一个节点,防止逻辑发生冲突
        disallowMultiple: false,
        // menu 用来将当前组件添加到组件菜单中,方便用户查找
        menu: 'NX/FLEX/AB',
    },

然后内部我们通过全局的视图绑定, 绑定到AB请求的返回值,去做页面的渲染, 对于我们而言就不需要判断, 页面渲染哪个组件了。内部逻辑都封装好了,我们只需要关系当前实验组的表现是怎么样的就好了。 如图:

image.png

image-20220528164215375


我介绍下这几个节点的意思


  1. container 节点只负责绑定自定义脚本AB组件,


  1. 然后container 下面的子节点 对应的其实就是不同的实验分组, 展示的不同node, 比如 命中了实验组1  那么我页面展示其实就是 展示 headerA 其他节点都隐藏

我们看下container 节点的绑定


点击下方的添加组件,然后找到我们对应的脚本组件AB如图:

image.png


然后我们根据提示信息,填写对应的配置就完成了AB 实验的搭建了, 页面 就可以渲染我们想要的结果了


image.png


这里的key 和value 都是由产品提供的,我们填写就好了, 然后实验应用了, 我们只需要把对应的节点删除了就好了, 代码层面不需要做任何改动。


react


我们在看看react 层面 我是如何去做的,这里是由组合组件的方式去实现的 一个


<ABTestComponent config={{ keyName: 'xx' }} fallbackComponent={renderDefault()}>
      <Variant name={'new1'}>
        <New1 />
      </Variant>
      <Variant name={'old'} />
    </ABTestComponent>


一个组件 ABTestComponent 和一个 变量 组件 Variant,这里为什么设置两个组件, 当时是这么考虑的 由于产品设置的实验组 可能有多个, 无法确定一个实验key 对应多少个value 。 所以干脆利用 react 的  props.children 去match 对应的子组件, 然后渲染就好了。


ABTestComponent 这个实验 你只需要传入 当前的实验key 就可以了,然后传一个兜底组件,这是边界情况考虑, 内部 做了兜底处理,防止页面崩溃。


然后  Variant 这个组件下面封装各种情况的组件, 你就不需要 大量的if else 了, 这个场景 比较单一可能还看出优势,我们在看下一个稍微复杂的场景如下:


<ABTestComponent config={{ keyName: 'xx' }} fallbackComponent={renderDefault()}>
  <Variant name={'new1'}>
    <ABTestComponent config={{ keyName: 'yy' }} >
      <Variant name={'new3'}>
        <New3 />
      </Variant>
      <Variant name={'new4'}>
        <New4 />
      </Variant>
    </ABTestComponent>
  </Variant>
  <Variant name={'old'} />
</ABTestComponent>


我这个用户 命中 实验xx 的new1 并且 在new 1的情况下 又分为 new3 和 new4 做一进步实验, 然后要做各种逻辑处理。用这种方式去处理的话,逻辑都已经分开了, 你只需写对应的展示 就好了, 如果应用了那一组, 你只需要在 组件 这块做删除就好了, 不用在各种方法删除, 提升代码的可稳定性 或者维护性。

相关文章
|
缓存 前端开发 小程序
数据驱动UI迭代,如何设计简单高效的前端AB实验方案?
以前,我们没有一条简洁而高效的AB实验接入方案,过去大多数前端在接到AB需求,唯一的选择就是调用客户端提供的库函数来实现,我们从中发现了一些痛点。
数据驱动UI迭代,如何设计简单高效的前端AB实验方案?
|
2月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
190 2
|
2月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
56 0
|
2月前
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
|
2月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
2月前
|
机器学习/深度学习 弹性计算 自然语言处理
前端大模型应用笔记(二):最新llama3.2小参数版本1B的古董机测试 - 支持128K上下文,表现优异,和移动端更配
llama3.1支持128K上下文,6万字+输入,适用于多种场景。模型能力超出预期,但处理中文时需加中英翻译。测试显示,其英文支持较好,中文则需改进。llama3.2 1B参数量小,适合移动端和资源受限环境,可在阿里云2vCPU和4G ECS上运行。
130 1
|
2月前
|
前端开发 算法 测试技术
前端大模型应用笔记(五):大模型基础能力大比拼-计数篇-通义千文 vs 文心一言 vs 智谱 vs 讯飞vsGPT
本文对比测试了通义千文、文心一言、智谱和讯飞等多个国产大模型在处理基础计数问题上的表现,特别是通过链式推理(COT)提示的效果。结果显示,GPTo1-mini、文心一言3.5和讯飞4.0Ultra在首轮测试中表现优秀,而其他模型在COT提示后也能显著提升正确率,唯有讯飞4.0-Lite表现不佳。测试强调了COT在提升模型逻辑推理能力中的重要性,并指出免费版本中智谱GLM较为可靠。
前端大模型应用笔记(五):大模型基础能力大比拼-计数篇-通义千文 vs 文心一言 vs 智谱 vs 讯飞vsGPT
|
3月前
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
|
4月前
|
存储 前端开发 JavaScript
前端语言串讲 | 青训营笔记
前端语言串讲 | 青训营笔记
52 0
|
6月前
|
JSON 前端开发 JavaScript
前端Ajax、Axios和Fetch的用法和区别笔记
前端Ajax、Axios和Fetch的用法和区别笔记
123 2