记一次解决小程序直播插件页面路由埋点问题
背景
路由埋点方案
自有埋点:基于wx.onAppRoute
做路由切换track、以及wx.onAppShow
和wx.onAppHide
做页面第一次打开/关闭/重新回到页面。
业务上用起来发现自有埋点直播插件页的数据与微信官方的数据差距有好几倍:
平台 | PV | UV |
---|---|---|
微信 | 774 | 115 |
自有 | 214 | 45 |
解决
实验找问题
根据实验后得出插件页面埋点存在问题:
-
直接打开直播插件页面
-
未能上报路由事件
-
后续的路由事件均不能上报
- 其他页面进入直播插件页面(正常)
- 直接打开其他非插件页面(正常)
怀疑/解释(因为得知存在问题是渐进的,不是一下子就知道存在的所有问题,所以提出的怀疑也是渐进的)
- 直播、网络状况,导致部分数据未能上报(基于直播页面有部分数据先甩锅🐶)
- 直接打开页面这种情况自有埋点不能支持
- 插件页面与正常页面不一样
提出解决方案:
解决自有埋点存在的问题(成本未知 上解)
使用第三方埋点:友盟、阿拉丁…看它们能否支持插件页面的路由事件上报(成本低 埋点数据在第三方 中)
直播插件提供组件,根据这些组件自己去实现直播页面(开发成本高 下)
1和2可以同步去做,3是实在没办法的一个选项
接入第三方埋点,测试后看数据,直接好家伙,根本不支持插件页面的路由事件上报
解决自有埋点存在的问题:
-
直接打开直播插件页面 未能上报路由事件
包装
App
函数// App const originalApp = App
App = function(this: any, obj: Object) { xProxy(obj, ‘onLaunch’, captureOnLoad) return originalApp.apply(this, arguments) }
-
解决直接打开直播插件页面后续的路由事件不能上报
-
真机测试找原因 -> 看看有没有报错信息
-
看文档猜测是插件调用 API 的限制
-
测试插件页面注册
wx.onAppRoute
/wx.onAppRouteDone
wx.onAppShow
和wx.onAppHide
虽然没报错,但是后续不会触发解决方案:包装
Page
(不会影响插件页面),当启动页面是插件页面时重新初始化路由上报let needReInit = false
function captureOnLoad(args: any) { if (args.path && isPluginPage(args.path)) { needReInit = true // 还需要主动上报一次路由 自己实现 } }
function xProxy(target: any, method: string, customMethod: Function) { const originMethod = target[method] // eslint-disable-next-line no-constant-condition if (originMethod || 1) { target[method] = function() { originMethod && originMethod.apply(this, arguments) customMethod.apply(this, arguments) } } }
function onPageLoad(this: any) { if (needReInit) { // 重新初始化事件监听 X.retrack() needReInit = false // 还需要主动上报一次路由 自己实现 } }
// App const originalApp = App
App = function(this: any, obj: Object) { xProxy(obj, ‘onLaunch’, captureOnLoad) return originalApp.apply(this, arguments) }
// Page const originalPage = Page
Page = function(this: any, obj: Object) { xProxy(obj, ‘onLoad’, onPageLoad) return originalPage.apply(this, arguments) }
-
测试发布
npm run test && npm run deploy
error ...
翻车
启动页打开直播插件页面后续的路由事件未上报,明明在埋点工程里面的demo还好好的,在业务项目里面翻了车。
对比demo和业务项目差异,只有Taro版本的问题了,demo是Taro 3,业务项目在Taro 2。
于是看了下Taro 2.x关于页面/组件方面的代码,最终发现Taro 2.x组件和页面都是用Component
去包的
我他妈,直接好家伙!
好吧,再包装一下Component
:
function onComponentPageShow(this: any) {
// 判断是不是页面
if (needReInit && this.$component.$componentType === 'PAGE') {
// 重新初始化页面埋点
X.retrack()
needReInit = false
// 还需要主动上报一次路由 自己实现
}
}
// Component
const originalComponent = Component
Component = function(this: any, obj: any) {
obj.pageLifetimes = obj.pageLifetimes || {}
xProxy(obj.pageLifetimes, 'show', onComponentPageShow)
return originalComponent.apply(this, arguments)
}
这次就可以了!
真实数据验证:
平台 | PV | UV |
---|---|---|
微信 | 579 | 112 |
自有 | 431 | 113 |
PV差距原因及修正思路:
原因:重复打开直播页面未上报路由埋点(打开后切后台,再回来)
修正思路:wx.onAppShow
和wx.onAppHide
切换成App
里面的onShow
和onHide
结论:
-
插件页面与正常页面不一样:
-
插件调用 API 的限制 启动页面是插件页面的时候需要考虑重新注册
-
插件页面的
Page
与全局的Page
是隔离的, 第三方基于包装Page
是不可能拿到插件的路由埋点(必须使用wx.onAppRoute
)
- Taro 2 的页面是用
Component
实现的