基本功能介绍
页面埋点
在页面的 onShow 勾子函数中上传埋点数据
曝光埋点
利用小程序提供的 createIntersectionObserver
API, 监听元素露出屏幕的事件,并触发回调(参数为元素的相关信息),由业务组件在回调中自己上传埋点数据。
1 | export class Exposure { |
由于业务需求,页面埋点和曝光埋点还需要有以下逻辑
1. 进入页面时(用户未操作),立即触发页面埋点和曝光埋点
2. 跳到其他页面再返回时,需要再次触发页面埋点和当前在屏幕露出的元素的埋点
页面埋点很容易处理,而曝光埋点很麻烦,因为 IntersectionObserver
只能监听元素可见性变化,无法静态获取是否露出元素,因此需要在每个页面监听 onHide
和 onShow
事件,在 onHide
时销毁所有监听实例,在 onShow
时重新监听(因为 IntersectionObserver
创建时会默认触发一次事件,即可达到重新触发曝光的目的)
但如果这些逻辑放在业务代码中,非常繁琐且重复,因此使用全局 mixin 处理。
二、 全局 mixin
页面埋点
每次 onShow 时都触发一次页面埋点
曝光埋点
首次 onShow 时初始化曝光埋点(初始化不在此控制,因为加载时机不同,所以放在在业务逻辑中)并将曝光埋点实例存在 exposureObservers 中以备后用;同时标记 isPageFirstLoad 为 false
每次 onHide 时销毁所有曝光埋点
下次 onShow 时,遍历并调用
exposureObservers
中的所有实例的reInit
方法
Mixin代码:
1 | /** |
Exposure修改为:
1 | export class Exposure { |
三、坑:iOS微信bug导致页面和曝光不准
1. 问题描述
iOS版本微信存在一个问题:从一个非TabBar页面A切换到TabBar页面B时,如果TabBar当前不处于目标页面B,会先短暂展示一下当前TabBar所在页面C,然后再切换到B。
结果就是页面C的 onShow
和 onHide
被执行,导致多发送一次页面和一批曝光事件。
除此之外,当二次复现此路径时,还会额外多触发一次B埋点,也就是发送2次B埋点。
相关链接
https://developers.weixin.qq.com/community/develop/doc/000ea812d54ab0cfea3a23eaf51400
2. 解决方案
过滤页面埋点
在调用 switchTab
前,记录全局变量 isSwitchingTab
(表示当前正在切换TAB)1
Vue.prototype.isSwitchingTab = 'pages/shopping-cart'
在全局 mixin 的 onShow 方法中,判断这个变量,如果当前页面路由和 isSwitchingTab
的值相同,才认为当前是真正想跳转的页面,而不是由于 bug 短暂展示的页面。这样就过滤掉了本就不应该触发的C页面的 onShow。
同时,在进入B页面 onShow 后,延迟2s清除 isSwitchingTab ,防止影响下次跳转。
1 | if ( |
此处还有一个点需要注意:在使用 getCurrentPages()
获取的页面栈中,并不包含C页面,只能在 this[__route__]
中读取当前页面的 route 属性。这说明对于微信小程序来说,C页面的意外展示是不被承认的,毕竟它连一个痕迹都木有留下。
过滤重复发送的B埋点
在发送埋点时,判断当前页面是否刚刚发送埋点,如果2s内有发送过,就不再发送
1 | // 防止重复曝光 |
四、最终代码
Mixin代码
1 | import { reportData } from '@/common/report-data' |
Exposure
1 | export class Exposure { |
五、调用方法
页面埋点
在页面组件中定义 pageTrackConfig
属性即可,无需额外处理
支持 String
和 Function
1 | // string |
曝光埋点
1 | // 参数:选择器(支持多个),曝光回调,当前组件实例(即this) |