这是我们团队号工程化系列的第六篇文章,将为大家介绍如何负责并完成团队中的前端性能优化工作。 全系列文章如下,欢迎和大家一同交流讨论:
- 字节三年,谈谈一线团队如何搞工程化一(全景篇)
- ⚡️卡顿减少 95% --- 记一次React性能优化实践(性能篇)
- Modal管理-看这篇文章就够了 (实践篇)
- 🍓中台表单技术选型实践(表单实践)
- 业务中后台用户体验优化方法论总结(体验篇)
- 🔥100 个应用加载性能提升 50%+ ------ 国际化业务中台性能优化实践(上)
- 🔥100 个应用加载性能提升 50%+ ------ 国际化业务中台性能优化实践(下)
团队尚有HC,感兴趣的小伙伴可以私信~(注明期望岗位城市:北京、上海、杭州)
前言 (PREFACE)
某日在电梯间遇到老板,打完招呼后陷入沉默,1s,2s,3s, 也许老板想体现对下属的关心,突然开始提问
👴老板:
最近平台的PV,UV是多少啊
👦 我(最怕老板突然关心):
大概是XXX
👴 老板:
怎么突然增加了这么多啊
👦 我(擦一下冷汗,这题我会,幸好前两天听产品说过):
因为最近上了一个分享有礼活动,流量一下子就起来了
👴 老板:
不错,那活动页面的停留时长是多少啊,转化率怎么样啊,新用户占了多少啊,其中的留存率是多少啊....
👦 我(沉默,沉默是我最后倔强, 我们都没相关的埋点,哪里来的数据这些数据分析啊):
老板,我们没有相关的埋点统计
👴 老板:
什么! 埋点都没有 ? ##$%#
以上情节纯属虚构,但是在实际的工作中,数据埋点与我们的产品息息相关,大部分业务的迭代以及收益衡量都离不开埋点数据的分析。
在小编所在的团队,负责的主要是中后台业务,没有拉新和转化的压力,按上述例子看埋点就显得无关紧要了。 实际的情况也是如此,在小编加入团队的初期,业务还处于高速发展期,团队业务基本都没有埋点数据,一切以完成业务功能诉求为主。
但小编本人认为不管什么类型的业务,埋点一定是不可欠缺的。
事实也是如此,举个例子,遇到一个业务诉求,某个模块的列表有太多的筛选项,我们想知道各个筛选项使用的频率,看是否可以做一些位置调整和取舍优化,但没有人能直接拍板如何进行调整和取舍。这时小编就推荐了前端埋点能力,辅助进行分析决策,最终顺利帮助产品完成了业务需求。 埋点,很多时候是能对决策做有利支持,也是能辅助发现隐藏问题的,甚至,完美应对老板关心的问题,让老板安静下来。那么,下面随小编一起来学习下基础的埋点知识吧。
什么是埋点(WHAT)
如果要用一个成语来形容埋点,就是"守株待兔",在特定的地方设定好特定的触发机制,等待用户来触发
埋点,它的学名是事件追踪(Event Tracking),主要是针对特定用户行为或业务过程进行捕获、处理和发送的相关技术及实施过程。埋点是数据领域的一个专业术语,也是互联网领域的一个俗称。
埋点是产品数据分析的基础,一般用于推荐系统的反馈、用户行为的监控和分析、新功能或者运营活动效果的统计分析
"前端埋点"作为埋点的一种主要方式,本质是记录和收集终端(App/H5/PC等)用户的操作行为,基本的实现原理是在通过采集代码,当用户的行为满足某种条件的时候,比如进入某个页面、点击某个按钮等,会触发采集记录和存储并上传,然后这些数据会被整合加以分析,在数据平台形成报表等被消费。
埋点采集上报流程示意图
PS: 本文的埋点仅指行为埋点,对于性能埋点不在这里讨论
👤 性能埋点:
👤 行为埋点:
为什么要埋点(WHY)
-
流量监测(按时间空间维度分析,留存分析,转化分析)
-
构建行为路径, 获取用户的整条行为链路,实现用户分群、人群洞察、行为细查等,构建用户画像
-
通过对埋点数据的处理、分析、建模,判断产品的效果和未来走向
-
为营销策略提供数据支持,分析营销效果,提高渠道转化
-
热力分析,帮助判断访客热衷的区域,评估网页设计是否合理等
-
实施 AB Test, 持续优化产品,使产品在市场上更具有竞争力
什么情况下需要埋点(WHO/WHEN//WHERE)
情景剧场
以下剧情纯属虚构,如有雷同纯属巧合
小情景A:
👧PM同学(激动万分):
同学们,我昨晚灵感突发,设计了一个巨🐂的功能,预计能提升产品XX的转化率,听我细说,它是......(two hours later)
👦RD同学(OS):
好复杂,听的头晕了
👦QA同学(OS):
手里好多需求在排期,这个工作量一看就很大,排不过来了😭
👴资深大佬(沉思片刻):
这个功能比较新颖,用户是否买账也没有具体的调研支撑,它的效果还有待论证,同时这个功能做下来要耗费我们XX+人力啊,个人觉得它的ROI不是那么高,咱们能不能先做下市场调研下,根据结果简化下,先做个MVP版本,加上埋点采集分析,根据数据来看下实际效果,判断后续的投入
小情景B:👧UED同学:
我们针对这个产品要进行改版优化,这次改版设计参考了%%¥#&#!.........,整体能更好的吸引用户,综上这是一件很重要的事,希望各位研发同学大力支持
👦FE同学:
怎么又要进行改版,上次改版才没过几个月,仅仅改个交互样式的能有大差别,还不如多做两个新功能实在,这个吸引用户怎么判断啊,有什么数据支撑嘛,怎么能看到实际效果呢?
👴资深大佬:
AB实验走起,埋点大法好,行不行咱们数据说话!
小情景C:👧运营同学(抱着一叠策划书):
老板,我们想做一个营销活动,预计能吸引XX新客,这些新客后续的留存率预估为XX,为产品整体提升XX转换率。所以,老板打钱💰!
🙎老板(战术后仰):
真的嘛,你不要骗我读书少啊🤔,那个谁,你觉得呢?
👴资深大佬:
老板,咱们可以对活动的进行全链路埋点,跟踪分析用户的数据,对本次活动的效果进行评估。如果效果好咱们可以考虑加大投入,多招点人做大做强
埋点场景
怎么埋点(HOW)
埋点类型
埋点方式多种多样,按照埋点位置不同,主要可以分为前端(客户端)埋点与后端(服务器端)埋点,本文主要讨论前端埋点
👤 后端埋点:
👤 前端埋点:
代码埋点 | 全埋点 | 可视化埋点 | |
---|---|---|---|
定义 | 针对想要的数据单独定义,并可以通过变量丰富埋点的信息,手动进行代码埋点,以支持上下游分析 | 数据采集sdk无区别的对待所有事件,将所有事件(页面的加载成功事件、模块的浏览和点击事件)全部获取后先存下来,到使用的时候,再根据具体的页面路径和控件名称,去捞取相应的数据 | 以可视化的方式,在页面中操作,选择埋点位置/模块,实现埋点采集上报。想埋哪里点哪里 |
原理 | 按需埋点,跟迭代运行,定义好埋点事件后添加相应埋点代码 | 通过SDK将程序中的数据尽可能多的采集、存储下来,以备后续消费使用 | 将核心代码与埋点配置分开,在可视化界面中编辑埋点信息生成埋点配置,从服务端拉取配置,根据配置监听相关交互操作并采集上报 |
工作量 | 引入SDK,根据需求添加埋点代码 | 引入SDK即可 | 引入SDK,可视化圈定并选择埋点模块 |
优势 | 按需采集,数据信息更聚焦和全面,可定制化 数据传输、存储消耗小 | 开发工作量小,仅前期引入SDK即可 数据链路完善,可通过行为数据钻取等,发现一些僵尸功能 | 开发工作量小,节省研发人力, 与研发流程解耦,产品、运营人员也单独进行埋点操作, 配置化,无需发版即可生效 |
劣势 | 需要人力定义、开发、验证 跟随版本迭代,需要发版 埋点代码和业务代码可能存在耦合 | 对比代码埋点单条数据信息内容少, 数据传输、存储消耗大,不能自定义事件 | 与代码耦合的问题,一旦对页面路径,模块名称位置等进行改动,埋点就会失效, 新增自定义事件比较困难, 可覆盖的范围有限,支持的埋点都是可视化元素触发 |
适用场景 | 埋点诉求复杂,需要为业务定制化的行为埋点 | 业务多变,但分析诉求比较轻量,不需要自定义事件的场景 | 业务页面多,且变动相对不是很频繁,有一定的分析场景但都能枚举, 用户行为可直接与页面可视元素挂钩 |
从工作量上来看 代码埋点 > 可视化埋点 > 全埋点
从准确性上来看:代码埋点 > 可视化埋点 > 全埋点
投入和产出成正比,但这里的对比有个前提,可视化埋点的基建工作不算在里面
埋点模型
埋点模型包含两个主要概念:事件(event) 、属性(params)
事件:通过埋点定义的用户行为或业务操作,比如页面打开,页面离开,模块曝光,模块点击
属性:事件附带的各种维度信息,比如用户信息,网络信息,设备信息,事件具体维度信息等
一个设计的相对完善的模型,一般包含用户行为五元素
通过这个可以详细的分析是谁在什么地方什么时间,怎么样进行了什么操作
举个🌰子:
埋点模型举例图
模型事件
仅供参考
- APP启动 ( AL )
APP应用专属,APP冷启动
- APP隐藏 (AH)
APP应用专属,APP隐藏到后台运行
- APP展现 ( AS )
APP应用专属,APP从后台运行切打开
- APP退出 ( AQ )
APP应用专属,APP程序销毁
- 页面打开( PV )
网页程序专属,页面打开
- 页面离开( PQ )
网页程序专属,页面离开
- 模块曝光( MV )
通用,模块的曝光事件
- 模块点击( MC )
通用,模块的点击事件
模型属性
仅供参考
-
用户属性
arduinouser_id // 用户ID user_name // 用户名称 uid // 应用唯一id
-
时间属性
arduinoevent_time // 上报的时间戳 time_zone // 时区
-
网络属性
arduinoip // ip地址 network_type // 网络类型 carrier // 运营商类型
-
设备属性
arduinodevice_type // 设备类型 device_id // 设备ID os_type // 操作系统类型 os_version // 操作系统版本 user_agent // 用户代理
-
地域属性
arduinocontry // 国家 city // 城市
-
应用基础属性
arduinoapp_version // 应用版本 app_id // 应用id app_name // 应用名称 env // 环境 source // 来源 -
埋点上报方式
当用户触发一个埋点被监听到时,埋点的上报通常分为三步
第一步:对数据进行处理加工,比如添加上who,when,where等信息
第二步:对数据进行队列化, 判断是批量上报还是单条上报,实时上报还是延迟上报等
第三步:对数据进行上报,发送请求进行上报
数据队列处理
从数量维度,分为批量和单条
从时间维度,分为实时和延迟
一般不做任何处理的情况下都是单条实时上报,在真实的项目场景下,当需要上报的数据量逐渐变多时,就需要考虑进行批量上报和延迟上报,本质上都是为了不阻塞业务程序的执行,上报本来就是用户无感知的事情,用户不能为此耗时买单(流量必须买单🐶)
无优化处理示意图
优化处理示意图
从数量维度上,将单条上报聚合成多条上报,大大减少了数量的请求(比如列表页每条数据的曝光事件)
从时间维度上,先本地化存储数据,将上报请求延后,优先处理业务逻辑请求,在程序空闲时进行上报
数据请求处理
传统 XHR 请求 | Image 对象 | Beacon ****API | |
---|---|---|---|
原理 | 直接将数据通过 ajax 发送到后端 | 用图片的src属性发送请求进行数据上报,一般采用1*1像素的透明 gif 进行上报,因为gif图片格式体积小 | 使用Beacon api 发送请求上报,Beacon api 是w3c新引入的补充性api,就是用来解决web页面在触发卸载销毁事件unload期间会中断所有异步xhr请求的问题 |
优势 | 灵活地设置请求头属性 针对POST, 能发送的数据量大 | 没有跨域问题,image 天然支持跨域。 不会阻塞页面加载,影响用户的体验。 src请求体量小,速度快 | - 页面销毁时的埋点请求不会中断 |
劣势 | 针对GET请求,存在安全问题,请求参数被暴露在IURL 中,同时GET请求在URL中传送的参数是有长度限制的,太大的数据量不适用, 页面销毁时还未上报成功的埋点大概率上报失败, 天然不支持跨域,需要进行设置 | 图片src 中的URL内容是有大小限制的,太大的数据量不适用,同样的安全性问题 | 只支持post请求,并且发送的数据量不会像正常xhr的post数据量那么大,最大数据量大小是由客户端(用户浏览器)版本决定的,chrome@70版本测试大概15MB左右(一般都够用), 浏览器兼容性问题 |
对于数据请求处理,主要考虑的有三个因素
- 跨域的问题
- 页面销毁时,如何保障还未成功上传的数据完成数据上传请求
- 大数据量的上传
这样看的话数据请求方式上没有银弹,每种方式都有一定的缺陷
所以,一般采用组合方式,根据数据量,选择Image或者Beacon的方式,若检测不支持Beacon, 在大数据量时回退到传统的XHR请求
埋点迭代(代码埋点)
埋点迭代流程
迭代流程示意图
流程中各阶段各岗位职责
阶段 | 事项 | 岗位人员 | 职责 | 重要产出 |
---|---|---|---|---|
需求阶段 | 埋点需求产出 | PM/运营 | 明确看数需求,明确埋点目标,产出埋点需求文档 | 埋点需求文档 |
埋点评审 | ALL | 参与评审并给出结论 | 评审结论 | |
设计阶段 | 埋点设计 | DA | 根据业务需求明确需要采集的内容和采集逻辑,设计具体埋点,产出埋点设计文档 | 埋点设计文档 |
开发阶段 | 埋点开发 | FE/RD | 根据具体埋点设计进行埋点逻辑开发开发后进行埋点自测 | 代码 |
测试验收阶段 | 埋点测试 | QA | 根据具体埋点设计进行埋点测试,检查漏埋,不规范属性、少报等信息,方式不限可人工对比,自动化脚本,或使用埋点验证工具等,最终产出埋点测试报告 | 埋点测试报告 |
埋点验收 | DA | 更进一步检查,验收埋点测试报告是否符合埋点设计的规则,产出埋点验收结论 | 埋点验收结论 | |
上线阶段 | 上线 | ALL | 包含代码在内的相关内容等上线,并线上验收 | 线上验收 |
分析总结阶段 | 数据分析 分析结论 | PM/运营/DA | 一般在项目运行一段时间后,拉取数据进行分析,根据需求阶段的目标,产出数据分类结论 | 分析结论 |
埋点注意事项(TIPS)
埋点好用,但不可乱用!
数据安全问题
-
埋点的数据里可能存在一些敏感信息,需要考虑脱敏或者在传输时进行加密,甚至在消费时也需要处理
- 针对国际化的业务,可能还要考虑数据存储相关的问题
-
埋点数据的消费需要有较完善的授权体系,不管是谁,最好不要给永久权限,对数据的下载等做强监控
埋点的准确性
模块曝光的时机
较为标准的针对模块曝光的定义:窗口可视区域内 && 组件矩形与视窗区域发生交集 && 交集垂线距离 >= 1px && 停留时间 >= XXms
针对列表或者瀑布流等模块,这种曝光定义的监听是相对比较麻烦且容易不准确的。那么就有比较偷懒的做法是直接拿到数据就全量上报,不考虑是否真的出现在窗口可视区域中。这样会导致上报数据不准,影响数据分析的结果。比如曝光到点击的转化率很低等
PV 事件上报的时机
PV是一个页面打开时第一个事件,埋点上报的时间应该早于该页面其他任何事件,但如果埋点不当,可能会有其他事件先于PV事件上报。
产生这种情况的原因,主要有两个
一是PV埋点代码的位置不对,触发时机晚于其他事件了
二是PV埋点上报里存在异步逻辑,导致执行晚了
mv事件(吃瓜.jpg):
pv事件(痛哭.jpg):
重复曝光和刷新机制
-
重复曝光
同一个模块多次出现是否需要去重
-
刷新机制
页面内模块的刷新,是否需要上报,若是,且有曝光去重机制,是否需要清空去重数据
对业务逻辑的阻塞
-
JS是单线程的,程序的运行必然会有消耗,如果阻塞了正常业务逻辑的运行,影响了用户体验,那就有点得不偿失了
-
请求的阻塞,埋点的上报数据请求过多,也可能会造成对正常业务数据的请求,同样也会对用户的交互响应有一定的影响
基于上述原因,一般埋点代码都在业务逻辑代码之后,同时也会包在单独的try catch
里,尽量把埋点代码的影响降到最低
另外上文埋点上报方式讲述到的数据队列中批量和延时的处理,也是为此服务
总结(SUMMARY)
理论篇从什么是埋点,为什么要埋点,什么情况下需要埋点,怎么埋点逐步带大家初步认识了埋点,另外根据个人遇到的一些问题提出注意事项。主要让大家了解到埋点的流程,关注埋点的重要性。
大部分情况下,想了解一个产品的运营情况,数据分析是最直观有效的方法,但是想要拿到具体的数据,就离不开科学合理的埋点,通过具体的分析,我们甚至能从中发现产品存在的问题或者值得优化的空间,为业务的发展带来一定的启发。
随着业务的发展和埋点知识的科普,埋点在团队的业务中也逐渐受到了重视,大家都学会用埋点去解决一些有争议的问题,针对团队具体的埋点流程,此处留个坑后续分享。