随着互联网发展,企业对于网站的PV、UV、用户的转化、新增和留存也愈来愈关注。而完整的数据采集是一切的前提。css
埋点即监控用户在应用表现层的行为,于产品迭代而言相当重要,运营,产品,数据分析基于此来对用户行为进行分析统计,同时埋点也可做为一种前端监控的手段,检验功能是否达预期的佐证。html
基于埋点数据进行用户行为分析,能够获得包含页面点击量、用户访问量、用户访问路径、用户转化率、导流转化率、用户访问时长和用户访问内容分析等重要数据。前端
经过埋点网站访问来源,能够统计用户入口分布,统计什么推广最有效,产品用户的汇集地方分布。vue
经过产品功能点击的埋点,统计知道用户感兴趣的是什么,便于产品运营更好的更新产品,取消或改进不感兴趣的产品。node
地理分布浏览器类型、网站停留时常、寻找产品用户群体,针对群体进行改进更新,以及对其余群体进行吸引等等。react
经过访问页面的注册用户数和页面 PV 的比值了解用户转化率。
经过导流页面PV和源页面 PV 的比值统计导流转化率。git
type - 上报类型
appid - 设备id
screen - 屏幕信息
userAgent - 浏览器信息
userInfo - 用户身份信息
timestamp - 上报时间
document.referrer - 访问来源
action - 上报事件的动做类型
element - 触发上报的元素
地理位置
访问渠道
以及其余自定义数据params等等github
前端埋点大体分为:代码埋点、可视化埋点、无痕埋点三种。json
如百度统计、友盟、TalkingData、Google Analytics、Sensors Analytics等都提供了这一方案。
使用相对简单,在APP或者界面初始化的时候,初始化第三方数据分析服务商的SDK,而后在某个事件发生时就调用SDK里面相应的数据发送接口发送数据。例如,咱们想统计APP里面某个按钮的点击次数,则在APP的某个按钮被点击时,能够在这个按钮对应的 OnClick 函数里面调用SDK提供的数据发送接口来发送数据。后端
除此针对特定需求也能够统一封装数据上报通用sdk,各页面各业务模块按需调用,同时埋点的形式也是多种多样的
// 上报sdk export const sdk = { params: null, initParams() { const params={}; params.domain = document.domain || ''; params.title = document.title || ''; params.referrer = document.referrer || ''; params.sw = window.screen.width || 0; params.sh = window.screen.height || 0; params.lang = navigator.language || ''; params.ua = navigator.userAgent || ''; params.loadT = window.performance.timing.domContentLoadedEventEnd - window.performance.timing.navigationStart || 0; params.timestamp= new Date(); sdk.params = params; }, report(params = {}) { // 上报 if(!sdk.params){ sdk.initParams(); } const _params = merge({},sdk.params,params); request('/api/report',{params:_params}); } }; // react wapper组件式 // 封装埋点包裹组件 export default function TrackerClick(props) { const { children, type } = props; return React.Children.map(children, child => { React.cloneElement(child, { onClick: (e) => { const originClick = child.props.onClick; typeof originClick==='function' && originClick.call(child, e); sdk.dispatch({type}); } }) }); } // 页面使用 <TrackerClick type="namespace.click"> <Button onClick={handleClick}>查看</Button> </TrackerClick>
// 通用方式 //上报事件的绑定类型对应的绑定名称 const REPORT_EVENT_FUNC = 'data-reporteventfunc'; //上报事件数据对应的绑定参数名称 const REPORT_EVENT_DATA = 'data-reporteventdata'; document.body.addEventListener('click',function(e){ if(e.target.getAttribute(REPORT_EVENT_FUNC)==='click'){ const str=e.target.getAttribute(REPORT_EVENT_DATA); sdk.report(JSON.stringify(str)); } }) // 页面-react <span data-reporteventfunc="click" data-reporteventdata={JSON.stringify({code:1,id:2})}></span> // 页面-vue <span data-reporteventfunc="click" :data-reporteventdata="JSON.stringify({code:1,id:2})"></span>
// 使用装饰器,剥离埋点与业务逻辑实现上的耦合,实现低侵入埋点 @tracker((params)=>request('/api/report',{params})) click(params){ // click业务... } const tracker = partical=>(target, key, descriptor)=>{ if (typeof partical!=='function') { throw new Error('tracker arguments is not a function ' + partical) } const oldValue=descriptor.value; descriptor.value=function(...args){ partical.apply(this,args); return oldValue.apply(this,args); } return descriptor; }
// Vue中经过mixin beforeRouteEnter(to, from, next) { this.enterTime=+ new Date(); }, beforeRouteLeave(to, from, next) { sdk.report({ type: 'visit', name: to.name, enterTime: this.enterTime, leaveTime: +new Date(), params: { from: { name: from.name, path: from.path, query: from.query }, to: { name: to.name, path: to.path, query: to.query }, } }) }
传统基于DOMContentLoaded、beforeunload、onload等也能够实现
<style> .tracker:active::after{ content: url("http://www.yzw.com/api/tracker/report?action=yourdata"); } </style> <a class="tracker">点击我,会发埋点数据</a>
埋点数据上报的形式
适用于须要接受数据上报后的返回结果进行回调处理
sdk.report=(params){ // 1.img标签 var img = document.createElement("img"); img.src = '/api/report?' + querystring.stringify(params); // 2.img对象 const img = new Image(); img.src='/api/report?' + querystring.stringify(params); // 3.script标签 var script = document.createElement("script"); script.src = src; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script); }
方案有Mixpanel、TalkingData、诸葛IO、腾讯MTA,Sensors AnalyticsV1.3+等
可视化埋点一般流程为:
输入页面的url =>
页面加载完成后 =>
配置可视化的工具 =>
点击建立事件(click) =>
进入元素选择模式 =>
用鼠标点击页面上的某个元素(例如button、a这些element)=>
就能够在弹出的对话框里面 =>
设置这个事件的名称(好比叫TEST),选上报数据属性(properties)=>
保存配置 =>
用户访问点击按钮 =>
数据上报
其中针对元素标记可能是利用xpath,是在xml文档中查找信息的语言,以下所示
const getPath = function (elem) { if (elem.id != '') { return '//*[@id="' + elem.id + '"]'; } if (elem == document.body) { return '/html/' + elem.tagName.toLowerCase(); } let index = 1, siblings = elem.parentNode.childNodes; for (const i = 0, len = siblings.length; i < len; i++) { const sibling = siblings[i]; if (sibling === elem) { return arguments.callee(elem.parentNode) + '/' + elem.tagName.toLowerCase() + '[' + (index) + ']'; } else if (sibling.nodeType === 1 && sibling.tagName === elem.tagName) { index++; } } }
经过上述方法,当咱们点击某个元素时,将触发的元素event.target传入,便可获得完整的xpath。
若是将其换作dom的选择器,相似:div#container>div:nth-of-type(2)>p:nth-of-type(1),由此,能够定位到具体的DOM节点
使用者在本身的网页引入 Sensors Analytics 的 JavaScript SDK 代码后,从 Sensors Analytics 的后台可视化埋点管理界面跳转到使用者的网站界面时,会自动进入到可视化埋点模式。在这个模式下,使用者在网页上点击任意 html元素时,Sensors Analytics 都会取到这个元素的url,层级关系等信息来描述这个 html 元素,当使用者设置了这个元素和某个事件相关联时,SDK 会把这些关联信息和客户生成配置信息,而且存放在 Sensors Analytics 提供的相应保存位置。当真正的用户以普通模式访问这个网页时,SDK 会自动加载配置信息,从而在相应的元素被点击时,使用 Sensors Analytics 的数据发送接口来 track 事件。
从上面咱们介绍的可视化埋点的方案能够看出,可视化埋点很好地解决了代码埋点的埋点代价大和更新代价大两个问题。可是,可视化埋点可以覆盖的功能有限,目前并非全部的控件操做均可以经过这种方案进行定制;同时,Mixpanel 为首的可视化埋点方案是不能本身设置属性的,例如,一个界面上有一个文本框和一个按钮,经过可视化埋点设置点击按钮为一个“提交”事件时,并不能将文本框的内容做为事件的属性进行上传的,所以,对于可视化埋点这种方案,在上传事件时,就只能上传 SDK 自动收集的设备、地域、网络等默认属性,以及一些经过代码设置的全局公共属性了;最后,做为前端埋点的一种方案,可视化埋点也依然没有解决传输时效性和数据可靠性的问题。
Heap、百度(点击猴子)、GrowingIO等
与可视化埋点又相似,两者的区别就是可视化埋点先经过界面配置哪些控件的操做数据须要收集;“无埋点”则是先尽量收集全部的控件的操做数据,而后再经过界面配置哪些数据须要在系统里面进行分析。
“无埋点”相比可视化埋点的优势,一方面是解决了数据“回溯”的问题,例如,在某一天,忽然想增长某个控件的点击的分析,若是是可视化埋点方案,则只能从这一时刻向后收集数据,而若是是“无埋点”,则从部署 SDK 的时候数据就一直都在收集了;另外一方面,“无埋点”方案也能够自动获取不少启发性的信息,例如,“无埋点”能够告诉使用者这个界面上每一个控件分别被点击的几率是多大,哪些控件值得作更进一步的分析等等。
固然,与可视化埋点同样,“无埋点”依然没有解决覆盖的功能优先,不能灵活地自定义属性,传输时效性和数据可靠性欠佳这几个缺点。甚至因为全部的控件事件都所有搜集,反而会给服务器和网络传输带来更大的负载。
技术实现上也能够经过拦截全局页面访问和事件响应,分析用户访问全流程路径,上报全部触发埋点,所以无埋点也叫全埋点。
  | 代码埋点 | 可视化埋点 | 无埋点 |
优势 | 可控性强,灵活性高,可定制各类特殊埋点需求,监测数据准确。 | 经过集成sdk,运营可自主选择,操做便捷,知足大部分场景 | 数据全面,不须要关注埋点逻辑,前端开发量轻 |
缺点 | 侵入型强,须要开发手动在相应位置进行埋点,增长维护成本 | 一般须要引入第三方,控件有限,技术上推广和实现起来有难度,须要运营配合 | 流量和采集的数据过于庞大,存在浪费、服务器性能压力大、难以特殊化定制 |
适用场景 | 适用于埋点量少、定制化程度高的需求 | 埋点量多,须要对数据深度整合分析 | 网站须要全埋点监控 |
每种方案各有优劣,并不存在某种广泛完美的能够适应一切场景的埋点方案,而是应该根据不一样的产品,不一样的分析需求,不一样的系统架构,不一样的使用场景,选择最合适的一种接入方案。下面是一些典型的例子: