什么是埋點(diǎn)?
埋點(diǎn)分析,是網(wǎng)站分析的一種常用的數(shù)據(jù)采集方法。數(shù)據(jù)埋點(diǎn)分為初級、中級、高級三種方式。數(shù)據(jù)埋點(diǎn)是一種良好的私有化部署數(shù)據(jù)采集方式。
埋點(diǎn)技術(shù)如何采集數(shù)據(jù),有何優(yōu)缺點(diǎn)?
數(shù)據(jù)埋點(diǎn)分為初級、中級、高級三種方式,分別為:
- 初級:在產(chǎn)品、服務(wù)轉(zhuǎn)化關(guān)鍵點(diǎn)植入統(tǒng)計(jì)代碼,據(jù)其獨(dú)立ID確保數(shù)據(jù)采集不重復(fù)(如購買按鈕點(diǎn)擊率);
- 中級:植入多段代碼,追蹤用戶在平臺每個界面上的系列行為,事件之間相互獨(dú)立(如打開商品詳情頁——選擇商品型號——加入購物車——下訂單——購買完成);
- 高級:聯(lián)合公司工程、ETL采集分析用戶全量行為,建立用戶畫像,還原用戶行為模型,作為產(chǎn)品分析、優(yōu)化的基礎(chǔ)。
無疑,數(shù)據(jù)埋點(diǎn)是一種良好的私有化部署數(shù)據(jù)采集方式。數(shù)據(jù)采集準(zhǔn)確,滿足了企業(yè)去粗取精,實(shí)現(xiàn)產(chǎn)品、服務(wù)快速優(yōu)化迭代的需求。
但,因手動埋點(diǎn)工程量極大,且一不小心容易出錯,成為很多工程師的痛。且其開發(fā)周期長,耗時費(fèi)力。無痕埋點(diǎn)成為市場新寵。
什么是無痕埋點(diǎn)
首先介紹一下傳統(tǒng)埋點(diǎn)存在的問題
- 數(shù)據(jù)質(zhì)量(埋錯、漏埋)
- 開發(fā)成本 (需要統(tǒng)計(jì)每個事件的點(diǎn)擊,頁面的展現(xiàn)pv uv)
無痕埋點(diǎn)就是為了解決這兩個問題,一行代碼完成統(tǒng)計(jì),無遺漏。
下面先介紹一下本公司vue實(shí)現(xiàn)埋點(diǎn)插件
function leStatic(actiontype, pagetype='',backup = {}){
...
...
};
Vue.prototype.$log = leStatic;
將埋點(diǎn)方法注冊到vue實(shí)例下;我們就可以使用 this.$log()來調(diào)用這個方法了,每調(diào)用一次這個方法就會埋上一個埋點(diǎn);
鋪墊完成,接下來該開始我們的表演了
1、我們的無痕埋點(diǎn)能做什么?
* 統(tǒng)計(jì)所有頁面內(nèi)事件的點(diǎn)擊量
* 統(tǒng)計(jì)頁面的展現(xiàn)量pv uv
2、怎么應(yīng)用?
應(yīng)用很簡單,只需要引入封裝的方法(Buried),并應(yīng)用在methods即可
import { Buried } from '@/libs/decorators';
@Buried
methods: {
...
}
3、需要注意什么?
- 此方法不局限在methods上是使用,只要是在單文件導(dǎo)出對象一級子對象下均可;
@Buried
components: {}
但是考慮到語義更加清晰建議在methods上使用此方法。
考慮到并不是所有的方法都需要設(shè)置埋點(diǎn),所以如果某方法不想設(shè)置埋點(diǎn) 可以 return 'noBuried' 即可忽略此方法不設(shè)埋點(diǎn)。
頁面展現(xiàn)量統(tǒng)計(jì)在鉤子函數(shù)中 (activated - created - mounted) 這三個鉤子內(nèi),所以頁面內(nèi)至少有這個三個鉤子之一才可統(tǒng)計(jì)頁面展現(xiàn)量。
4、話不多說,先上代碼?
/**
* @description 全埋點(diǎn)
* 1.在所有methods方法中埋點(diǎn)為函數(shù)名
* 2.在鉤子函數(shù)中 (activated - created - mounted) 依次尋找這三個鉤子
* 如果存在就會增加埋點(diǎn) VIEW
*
* 用法:
* @Buried
* 在單文件導(dǎo)出對象一級子對象下;
* 如果某方法不想設(shè)置埋點(diǎn) 可以 return 'noBuried' 即可
*/
export function Buried(target, funcName, descriptor) {
let oriMethods = Object.assign({},target.methods),
oriTarget = Object.assign({},target);
// methods方法中
if(target.methods) {
for(let name in target.methods) {
target.methods[name] = function () {
let result = oriMethods[name].call(this,...arguments);
// 如果方法中返回 noBuried 則不添加埋點(diǎn)
if(typeof result === 'string' && result.includes('noBuried')) {
console.log(name + '方法設(shè)置不添加埋點(diǎn)');
} else if(result instanceof Promise) {
result.then(res => {
if(typeof res === 'string' && res.includes('noBuried')) { console.log(name + '方法設(shè)置不添加埋點(diǎn)'); return; };
console.log('添加埋點(diǎn)在methods方法中:' , name.toUpperCase ());
this.$log(name);
});
}else{
console.log('添加埋點(diǎn)在methods方法中:' , name.toUpperCase ());
this.$log(name);
};
return result;
}
}
}
// 鉤子函數(shù)中
const hookFun = (funName) => {
target[funName] = function() {
let result = oriTarget[funName].call(this,...arguments);
console.log('添加埋點(diǎn),在鉤子函數(shù)' + funName + '中:', 'VIEW');
this.$log('VIEW');
return result;
}
}
// 鉤子函數(shù)中 view
if (target.activated) {
return hookFun('activated');
} else if (target.created) {
return hookFun('created');
} else if (target.mounted) {
return hookFun('mounted');
};
}
簡單的實(shí)現(xiàn)了無痕埋點(diǎn)的實(shí)現(xiàn)方案,目前在項(xiàng)目中運(yùn)轉(zhuǎn)正常。大大減少了開發(fā)者的工作量,預(yù)防了賣錯、漏埋導(dǎo)致上線后無數(shù)據(jù)統(tǒng)計(jì)情況發(fā)生。如果有更好的建議,請聯(lián)系我哦~