好玩的JS系列--小程式資料埋點
小編推薦:Fundebug專注於JavaScript、微信小程式、微信小遊戲,Node.js和Java實時BUG監控。真的是一個很好用的bug監控費服務,眾多大佬公司都在使用。
前言
最近負責的一個專案,專案的客戶端是微信小程式。客戶提了需求,需要進行資料埋點,收集使用者行為資料,為後續提升使用者體驗及產品優化提供基礎資料收集。於是在一個風和日麗的日子,擼起袖子動手幹。
思路
先看看客戶端常見的資料埋點方案如下圖。
資料埋點方案.png
侵入式埋點這個如果在頁面少,資料收集需求變化不大的情況下,還是挺經濟實惠的。鑑於當前專案頁面較多,資料收集的需求變化也在不斷的調整,所以侵入式埋點的方案不適用本專案,只有鬆耦合這個方案了。
小程式的特點
根據鬆耦合埋點方案,首先要解決的問題是攔截小程式所有控制元件的操作資料。在Web中有BOM物件及DOM物件可以給我們進行全方位的操作,特別是BOM物件,可以進行全域性事件攔截。而小程式類似BOM物件的主要有下面三個物件:App、Page、Component。
- App:App物件有且只有一個,屬於小程式的總控物件,App下面包含著n個Page物件。
- Page:Page則通過字面理解就是頁面的總控物件,一個小程式可以有多個Page,每一個Page物件對應一個頁面,Page下面可以包含n個Component及其他普通的小程式元件。
- Component:
小程式的事件機制也是採用與JavaScript一樣的事件機制,捕獲->執行->冒泡的機制,JavaScript在BOM及DOM物件中都提供了addEventListener這種訂閱/釋出機制,使我們可以輕鬆的攔截所有的事件,又不影響現有的流程及程式碼,從而實現鬆耦合埋點方案。但是小程式沒有提供addEventListener的訂閱/釋出機制,沒有辦法通過這樣子的方案來實現。
1.攔截器方式
翻了官網,發現沒有辦法統一的處理,那麼只能退而求其次,減少對現有的程式碼的侵入,於是想到了攔截器的機制來實現。
看看下面小程式原生的程式碼
App({
onLaunch(options) {
// Do something initial when launch.
},
onShow(options) {
// Do something when show.
},
onHide() {
// Do something when hide.
},
onError(msg) {
console.log(msg)
},
globalData: 'I am global data'
})
提供攔截器,這裡只拿App的onLaunch事件進行示例,其他事件都差不多這樣處理即可。
var appFilter = function(config){
if(config.onLaunch){
let _onLaunch = config.onLaunch;
config.onLaunch = function(ops){
//在這裡幹埋點的事
//例如儲存資料、上送資料
_onLaunch.call(this);//呼叫原來的執行邏輯
}
}
return config;
}
//App使用攔截器示例
App(appFilter({
onLaunch(options) {
// Do something initial when launch.
},
onShow(options) {
// Do something when show.
},
onHide() {
// Do something when hide.
},
onError(msg) {
console.log(msg)
},
globalData: 'I am global data'
})
)
這個也是JS好玩的地方,一切皆為物件。通過新增一個Function物件,增強方法之後,把舊的Function物件進行替換。上面的App的onLaunch方法,經過appFilter過濾器的處理後,就替換成過濾器裡面加了埋點事件的新方法了,對於開發人員來講,不需要去改動原來App.onLaunch事件裡面的程式碼,目的達到了,但是不夠完美,在寫過濾器的實現邏輯時,給了我一個靈感,我是否可以用這種方式來實現不侵入程式碼的埋點?答案是可以的。
2.增強擴充套件方式
利用新增一個Function物件,增強方法之後,把舊的Function物件進行替換這樣的原理,依次將App、Page、Component這三個物件進行增強擴充套件,示例程式碼如下。
//先把原生的三個物件儲存起來
const originalApp = App,
originalPage = Page,
originalComponent = Component;
//在原生的事件函式裡面,新增資料埋點,並替換成新的事件函式
const _extendsApp = function (conf, method) {
const _o_method = conf[method];
conf[method] = function (ops) {
//在此處進行資料埋點
if (typeof _o_method === 'function') {
_o_method.call(this, ops);
}
}
}
//重新定義App這個物件,將原來的App物件覆蓋
App = function(conf){
//定義需要增強的方法
const methods = ['onLaunch', 'onShow', 'onHide', 'onError']
methods.map(function (method) {
_extendsApp(conf, method);
})
//另外增強擴充套件埋點上送的方法
conf.william = {
addActionData: function (ops) {
console.log('addActionData');
},
addVisitLog: function (ops) {
console.log('addVisitLog');
}
}
return originalApp(conf);
}
//Page及Component物件類似App的處理即可
至此,整個小程式的生命週期都在掌握之中了,可以按需採集對應的資料,並且對於開發人員來講,還不需要去修改及調整程式碼,鬆耦合埋點方案搞定。
3.增強擴充套件+訂閱/釋出
上面的實現方案雖然實現了鬆耦合,但是個人覺得還不夠完美,埋點的動作必須要寫在增加的方法裡面,這樣子可維護性較差,也不夠靈活。解耦這事現在對我來說信手拈來,祭出了我的EventHub(基於訂閱/釋出模式實現的訊息匯流排),完美。
//引用EventHub
import EventHub from '../../utils/eventhub.min';
//先把原生的三個物件儲存起來
const originalApp = App,
originalPage = Page,
originalComponent = Component;
//在原生的事件函式裡面,新增資料埋點,並替換成新的事件函式
const _extendsApp = function (conf, method) {
const _o_method = conf[method];
conf[method] = function (ops) {
//在此處進行資料埋點
//此處改成訊息釋出
if (typeof EventHub != "undefined") {
EventHub.emit('app' + method, ops);
}
if (typeof _o_method === 'function') {
_o_method.call(this, ops);
}
}
}
//重新定義App這個物件,將原來的App物件覆蓋
App = function(conf){
//定義需要增強的方法
const methods = ['onLaunch', 'onShow', 'onHide', 'onError']
methods.map(function (method) {
_extendsApp(conf, method);
})
//另外增強擴充套件埋點上送的方法
conf.william = {
addActionData: function (ops) {
console.log('addActionData');
},
addVisitLog: function (ops) {
console.log('addVisitLog');
}
}
return originalApp(conf);
}
//Page及Component物件類似App的處理即可
這樣子就可以把埋點處理的邏輯抽離到另外一個JS檔案中去實現。
EventHub.on('apponLaunch',function(ops){
//在這裡可以處理資料埋點的事
})
延展性思考
基於上述的實現方案,我們除了增強生命週期,也可以像上面那樣去增加公用的方法,例如App.william.addActionData,更可以通過增強setData方法來進行資料溯源或者進行差量比較來提升效能等方式。
作者:飆豬狂
連結:https://www.jianshu.com/p/3253a15707fc
關於Fundebug
Fundebug專注於JavaScript、微信小程式、微信小遊戲、支付寶小程式、React Native、Node.js和Java實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了9億+錯誤事件,得到了Google、360、金山軟體、百姓網等眾多知名使用者的認可。歡迎免費試用!