1. 程式人生 > >(轉)前端埋點的那些事

(轉)前端埋點的那些事

info 資深 實時數據 特征 oca 負責 一次 滴滴 維護

為什麽要埋點?現在的互聯網公司越來越關註轉化、新增、留存,而不是簡單的統計PV、UV。而完整的數據采集是一切的前提。

埋點包括在IOS、Android、H5、小程序等前端埋點,也包括後端業務埋點。這裏僅僅講講這些年和產品經理、運營撕逼上百個回合的前端埋點內容。

說說手工埋點可視化埋點無埋點區別

手動埋點(代碼埋點)

純手動寫代碼,調用埋點SDK的函數,在需要埋點的業務邏輯功能位置調用接口上報埋點數據,友盟、百度統計等第三方數據統計服務商大都采用這種方案;

手動埋點讓使用者可以方便地設置自定義屬性、自定義事件。所以當你需要深入下鉆,並精細化自定義分析時,比較適合使用手動埋點。

手動埋點的缺陷就是,項目工程量大,需要埋點的位置太多,而且需要產品開發運營之間相互反復溝通,容易出現手動差錯,如果錯誤,重新埋點的成本也很高。這會導致整個數據收集周期變的很長,收集成本變的很高,而且效率很低。因為手動埋點需要開發人員完成,所以每次有埋點更新,或者漏埋點,都需要重新走上線發布流程,更新成本也高,對線上系統穩定性也有一定危害。

手動埋點的技術本質是什麽呢?

我們看看從javascript中能輕松獲得哪些信息:

域名:document.domainURLdocument.URL
頁面標題:document.title
分辨率:window.screen.height & window.screen.width
顏色深度:window.screen.colorDepth
Referrer:document.referrer
客戶端語言:navigator.language

除了上面的列舉的常規信息以外,還有大量的業務數據,都需要通過手動寫javascript去實現。

代碼手動埋點常用的方式有以下幾種:

  • 命令式
$(document).ready(()=>{
// ... 這裏是你的業務邏輯代碼
sendData(params);  //這裏是發送你的埋點數據,params是你封裝的埋點數據
});
// 按鈕點擊時發送埋點請求
$(button).click(()=>{
// ... 業務邏輯
sendData(params); //同上
});
這裏的sendData有很多種方式,比如基於ajax發送json數據,或者使用url連接帶上params,或者使用一像素圖片帶上數據,在或者使用head帶上埋點也可以。封裝方式多種多樣。

  • 聲明式
<button data-mydata="
{key:‘uber_comt_share_ck‘, act: ‘click‘,msg:{}}">打車</button>

這裏聲明了自定義屬性data-mydata,你可以在你的SDK中去掃描和識別這些自定義屬性,並解析封裝數據,在SDK中按照自定義規則去綁定事件並發送埋點數據。

  • 前端框架式
    如果使用Vue或者React等前端框架,這些框架都有自己的各種生命周期,為了減少重復性的手動埋點次數,可以在各個生命周期位置,根據你的需求封裝你所需的埋點。比如你是SPA單頁應用,你希望在每一個頁面的componentDidMount埋點,並由此確定用戶已經打開了頁面。

  • css埋點:
.link:active::after{
    content: url("http://www.example.com?action=yourdata");
}
<a class="link">點擊我,會發埋點數據</a>
  • 這裏使用了很巧妙的css的某些特征,這些可以觸發發送請求的特征。

以上是比較常見的手動埋點方案,當然還有很多其他方式和有待挖掘的方案。也請大家補充。

可視化埋點(框架式埋點、無痕埋點)

解決了純手動埋點的開發成本和更新成本,通過可視化工具快速配置采集節點(圈點),在前端自動解析配置,並根據配置上傳埋點數據,比起手動埋點看起來更無痕,這裏的配置數據可以設置過濾條件,避免針對所有元素(比如全埋點),可以在調用開啟自動監控API時通過設置一些特征屬性,來過濾不符合條件的元素,實現只針對某些元素進行自動上報數據的需求。

比如國外比較早做可視化的是Mixpanel,國內較早支持可視化埋點的有TalkingData、諸葛IO,2017年騰訊的MTA也宣布支持可視化埋點;相比於手動埋點更新困難,埋點成本高的問題,可視化埋點優化了移動運營中數據采集的流程,能夠支持產品運營隨時調整埋點,無需再走發版流程,直接把配置結果推入到前端,數據采集流程更簡化,也更方便產品的叠代。

可視化埋點中多數基於Xpath的方案,XPath 是一門在 XML 文檔中查找信息的語言。XPath 可用來在 XML 文檔中對元素和屬性進行遍歷。

技術分享圖片

比如上圖中標識的位置,其中的xpath是://*[@id="projects"]/a4/img,如果換成DOM的selector:#projects > a:nth-child(4) > img。通過這些信息可以精準定位到一個DOM節點,xpath方案分為精確路徑和概略路徑兩種做法,精確路徑從被點擊的元素不斷向上冒泡查找到根節點,並記錄過程中每個節點的。如果用戶阻止了冒泡會導致失效,概略路徑是在前者的基礎僅僅向上查找白名單中的節點。但是如果DOM節點有任何變化,對應的xpath數組就是被打亂,很容易影響采集。

可視化埋點配置化能力相對手動埋點更強,是對手動埋點的補充而不是代替,很多手動埋點點都可以通過好的規劃和架構變為可視化埋點。

無埋點(自動埋點、全埋點)

無埋點並不是沒有任何埋點,所謂只是不需要工程師在業務代碼裏面插入侵入式的代碼。只需要簡單的加載了一段定義好的SDK代碼,技術門檻更低,使用與部署也簡單,避免了需求變更,埋點錯誤導致的重新埋點。

通過這個SDK代碼,前端會自動全量采集全部事件並上報埋點數據,能夠呈現用戶行為的每一次點擊、每一次跳轉、每一次登錄等全量、實時用戶行為數據,這些數據傳到後端後,可通過用戶分群、漏鬥對比等功能,分析不同訪問來源、不同城市、不同廣告來源等多維度的不同轉化細節,細而全。

技術分享圖片

圖中可以看到無埋點會發送大量的請求,因為無埋點會針對很多DOM節點添加事件。當用戶在頁面中有交互時,就會觸發大量的數據請求。

無埋點相比可視化埋點,在解決數據“回溯”問題上更有優勢,如果你想分析某一天某個控件的點擊情況,如果你沒有針對這個按鈕做可視化埋點,則只能從你針對這個按鈕做可視化配置的這一時刻之後才有埋點數據,而無埋點,則從你部署SDK那一刻就一直有數據在收集;無埋點做熱力圖也更有優勢,無埋點可以告訴使用者這個界面上每個控件分別被點擊的概率是多大,通過熱力圖清晰可見。

無埋點的劣勢是自定義屬性不靈活,傳輸時效性差,數據可靠性欠佳,耗費網絡流量,還會增加服務器負載,而且兼容性也不佳。

據說Heap Analytics在2013左右較早推出了無埋點方案,但是網上有人透露百度在2009年就有類似技術,後來2011年,百度質量部也推出過一個內部服務,用以錄制安卓 App 的全部操作,通過回放定位App崩潰的原因;豌豆莢也在2013年左右在自己的 App 內,也記錄了所有控件操作情況。國內GrowingIO在2015年也較早支持了無埋點方案,後面神策等其他第三方也陸續支持了此技術。

我們看看神策和Mixpanel對無埋點的實現方案。

  • 神策: 根據官方的介紹,設置AutoTrack之後,SDK就會自動解析HTML頁面上的( a 、 button 、 input )標簽。 並記錄這些標簽的點擊情況,一旦頁面某一個按鈕發生了點擊行為,SDK就會去采集此按鈕的一些信息,例如: 這個按鈕的標簽類型,這個按鈕的文本內容,這個按鈕的 name ,這個按鈕的 id 、 class 名,還有一些按鈕特有的屬性如 href等。

  • Mixpanel: 設置AutoTrack之後,SDK會監測頁面上的所有 form表單 、 input標簽 、 select和textarea標簽 產生的 submit 、 change 、 click 事件,並采集這些標簽上的屬性一起上報。

無埋點確實發送的埋點數量很巨大,比如知乎上就有很多人質疑無埋點解決方案。很多用戶對無埋點發送大量埋點請求表示不理解,但是由於無埋點技術方案的限制,無埋點的可交互元素眾多,每一次交互都會發送請求,所以會導致網絡請求過重。神策等官方文檔中也建議無埋點最好使用在那些按鈕不是很多的,相對簡單的頁面。

數據采集能力比較

比如這個頁面,點擊確認按鈕,如果使用無埋點和可視化埋點,在這裏可能只能獲取到某時刻某個人點擊了確認,提交了一個訂單,僅此而已。如果你希望拿到裏面的首付款,月供,車型車款、用戶詳情等深度業務信息,就只能靠手動埋點獲取。

無埋點和可視化埋點雖然使用和部署都很簡單,但是在數據精確度和詳細程度的獲取能力上代碼埋點更強大。一般來說,我們的產品都是根據業務場景混合使用三種埋點模式來完成我們的數據收集。

感性認識一些數據上報格式和接入代碼

上報方式提到過,基本就是json、url params、head等,為了數據分析的關聯性,會帶上cookie、還有一些數據可能是在localstorage等具有生命周期管控的客戶端存儲裏。

GA的接入代碼:

技術分享圖片

GA的上報格式:

技術分享圖片

Talkingdata的接入代碼:

技術分享圖片

Talkingdata的上報格式:

技術分享圖片

埋點技術除了剛才的方式劃分,還可以劃分為前端埋點和後端埋點,後端埋點數據更可靠、更集中(且沒有前端的多端問題)、更實時。這篇文章主要是討論前端埋點。

根據工作中對埋點的對比和整理,我們簡單比較部分埋點方案:

對於語義明確的UI事件,自動埋點的數據一般會比手動埋點更加準確,更貼近用戶行為,也更節省開發成本,侵入性更低。

主要是因為自動埋點語義簡單明確,不像手動埋點由於開發習慣、代碼風格、人的理解誤差、分支處理等各種不確定因素變得沒那麽清晰明了。

比如:“下單”事件,自動埋點的PV肯定是>=手動埋點的,而UV差別可能不大。分析開發代碼發現在onClick Listener中包含其他未覆蓋到的分支,差別很可能就在代碼分支當中。如果更進一步分析下代碼可以發現,為什麽開發不在分支當中埋點?可能這個分支會認為用戶的這一次點擊是“無效”的,但這只是程序邏輯的看法,用戶可能不這麽認為,用戶很可能會覺得很奇怪沒反應,然後再點一次。這些手動埋點不易察覺的細節,自動埋點都能記錄,所以說,自動埋點在這些情況下會更貼近真正的用戶行為。

自動埋點可降低原來手動埋點的個數和復雜性,使之更簡化
比如:進入“商品詳情頁面”(展現),目前包括5個手動埋點,實際上用自動埋點只需要一個就夠了,而且自動埋點不會遺漏。從數據來看,一個自動埋點的PV已經超過5個手動埋點之和。

自動埋點可采集界面環境數據,但是數據不夠純,需要進一步去噪
自動埋點能采集到大部分用戶“看到的而且有用數據”。比如:“價格”這一屬性,手動埋點可直接定義“amout: 5.2“來輕松獲取數據,而自動埋點獲取的是一串文本: “價格預估5.2元”,若要獲取精確的5.2這個數值,就需要進一步解析。

自動埋點無法替代手動埋點,但可大大減少手動埋點工作量可預想的是,在用戶行為分析上,自動埋點可以滿足很大一部分需求函數級的埋點無法用自動埋點代替,後臺非UI的事件也無法用自動埋點代替,自動埋點無法攜帶當時的業務場景數據,這些都表明了自動埋點無法完全替代手動埋點。

但單就用戶行為分析來講,自動埋點是可以覆蓋用戶的一些基本行為路徑的,並能做一些較淺層次的分析。如果需要探究用戶行為背後的原因、或需要進一步深入分析行為的時候,就是需要更多的後臺邏輯事件、需要攜帶更多屬性值的時候,就需要通過手動埋點來完成。所以,但是深層次的分析是你的重點,就需要使用手動埋點來解決。

埋點類型雖然當前也就這幾類解決方案,而且真實的使用請求會根據業務混合使用多種埋點類型。但是我們除了選擇好埋點類型外,要展開埋點工作,面臨的溝通協調,如何準確多團隊達成共識,並確保各方對業務和埋點深度理解,做要的工作和面臨的挑戰會更大。想要做好埋點工作,埋點需求的整理很重要,且需要遵守一定的原則,所以我們引用滴滴內部Omega團隊針對這些原則的整理(本來很多內容均采用了Omega團隊的日常工作整理,Omega是滴滴內部服務的強大數據采集和分析平臺,期待Omega開源或開放的一天,在此感謝滴滴Omega團隊的深度沈澱):


埋點需求整理原則

原則是基於一系列問題展開,並基於這些問題確定埋點需求,我作為FE的RD,針對這些原則,雖然至今也沒有真正全面的做到,但是如果遵循這些原則,將會受益良多(也歡迎大家補充問題內容),當你能清楚的回答這些問題,埋點工作將會更順利的開展:

3個H,5個W

HOW LONG:

  • 埋點可用周期是多久,持續幾個版本可以?
  • 生命周期結束後是否可以考慮下掉?

    HOW MUCH:

  • 現有的埋點哪些可以滿足我的部分埋點需求?
  • 哪些現有的埋點可以替代我要的部分埋點?
  • 新的埋點有多少?這些埋點是否是最必要的?

    HOW:

  • 怎樣證明新功能效果?
  • 需要哪些埋點?
  • 我該怎麽埋這些點?
  • 部分埋點的計算邏輯是什麽?
  • 數據結果怎麽看?漏鬥?同環比?

    WHO:

  • 我的產品設計面對的用戶群裏是誰?
  • 用戶特征是什麽?
  • 這部分特征用戶對功能預期的數據結果是什麽?
  • 用戶習慣是什麽?

    WHAT:

  • 我的新產品是什麽?
  • 新產品包含哪幾個模塊?

    WHY:

  • 涉及新產品的目的是什麽,為了解決什麽問題?

    WHERE:

  • 新功能展示在產品端的哪個位置?
  • 在哪些版本生效?
  • 哪些功能的展示或作用在哪裏需要跟服務端等交互?

    WHEN:

  • 功能是在用戶場景什麽時候調用產生?
  • 調用過程中什麽時候和服務端交互?
  • 功能調用正常情況下需要大概需要多長時間?
  • 什麽情況會影響調用結果?
  • 調用有風險的時候,是否需要加監測?

理清楚了埋點的思路,要讓埋點順利進行,且不影響線上功能,則需求嚴格的埋點規範和治理方案。

埋點規範

某些企業,保守估計,手動埋點的錯誤率可能會高達50%,比如一些簡單頁面的進入應該埋在 viewDidAppear(didMount...),按鈕點擊應該埋在 onClickListener等等都經常被開發弄錯。埋點工作本身並不難,是純粹的體力活,但是要展開一個好的埋點工作,需要BI先梳理,然後再傳達給RD,然後RD再去開發實現,最後應該經過測試驗收,因為沒有統一的標準,每個人的理解不一樣,就很容易弄錯,後面會和大家在詳細聊聊埋點規範的問題。

我們了解的一些大公司,像Facebook等矽谷公司已經將埋點看得與產品設計同等重要,新功能還在設計階段就先把衡量指標及埋點梳理好,而具體負責埋點的RD也是團隊中最資深的RD(如果不是專職的話),RD需要每天不斷的與BI溝通確保語義一致。

而我待過的滴滴、陸金所等公司的現狀是,埋點的RD很多時候都是隨機任務分工的,甚至經常被安排給實習生,埋點質量難以保證。還有一種情況是產品為了快速上線需求,一味追求上線速度,在需求評審階段沒有梳理和提出埋點需求,上線後臨時插入埋點需求,在未經過分析理解和測試驗收的情況下匆匆加入埋點代碼,而且測試經常也不重視測試(提出免測),導致埋點錯誤,甚至是業務代碼錯誤等線上問題。這種情況下自動埋點既能減少溝通開發的工作量,又能降低埋點出錯的概率。所以,自動埋點更適合公司在埋點規範沒有完全建立,埋點質量普遍不高的階段。但是公司體量到一定程度後,RD和產品經理將會更頻繁的和手動埋點接觸,我們作為一個手動埋點的深度用戶團隊,談談我自己的對手工埋點的痛點梳理:

  1. 埋點混亂
  2. 常常埋錯,漏埋
  3. 業務變化後,老埋點數據失去意義
  4. 埋點數據無人使用,浪費資源
  5. 數據團隊、研發團隊、產品團隊協作配合難度大
  6. 很多時候不太重視數據,而是重視業務的快速上線
  7. 埋點語義不明確,同一個按鈕存在多種描述,不易檢索
  8. 無用/重復埋點太多,幹擾了正常埋點數據
  9. 大量存量埋點Owner離職或者轉崗,導致大量僵屍埋點信息

那麽如何避免以上問題呢?建立一個好的規範非常重要,包括命名規範和流程規範。

埋點命名規範

我們當前的做法是埋點名稱只能是由字母、數字、下劃線組成,並保證在應用內唯一,比如sw是展示,ck是點擊。

常用規則的舉例如下:
比如行為埋點:{團隊|業務|角色}_{組件|頁面}_{具體元素}_{動作}
示例:
yourteam_fc_all_msg_ck
autoplatform_flowtab_sw : autoplatform代表業務線,flowtab 代表功能,sw代表頁面操作,sw是展示,ck是點擊
uber_comt_share_ck :uber業務線,comt評價組件,share分享按鈕,ck點擊

埋點流程規範

如果你發現每天有大量埋點錯誤反饋,並導致很多錯誤的分析結論,一個錯誤的分析結果還不如沒有數據分析結果。造成這個問題的原因包括:

  1. 前端埋點涉及復雜的交互,難以找準埋點位置;
  2. 埋點的驗收流程不完善,沒有經過測試和產品經理的測試和驗收,驗證不完備;

好的埋點需求應該和業務功能需求同等重要,也需要經歷軟件開發的整個生命周期,如果能嚴格按照一個規範的流程處理埋點,以上問題會得到更好的解決。

規範內容

需求階段:

確定埋點信息,核心包括五方面信息:事件ID、埋點名稱、埋點描述、埋點屬性以及截圖。

舉例:

  • 快車頁面打車的埋點信息為:
  • 埋點ID為:gulf_p_f_home_order_ck
  • 埋點名稱為:呼叫快車
  • 埋點描述:在快車首頁點擊呼叫快車按鈕。

如何落地:

如果不按照規則和流程埋點將不會上報相關數據,制定強制規定。

開發什麽功能:

埋點全文檢索能力、自動找到重復埋點(語義相近或者數據相近)功能。

開發階段:

務必和開發溝通,並讓開發在完全理解業務語義的情況下,在前端按照埋點代碼規範進行埋點。

舉例:

比如針對商品購買按鈕,在前端點擊方法的第一行調用SDK,最好也傳入文本字面描述。

如何落地:

靜態代碼檢查。

開發什麽功能:

開發探測每個埋點對應到的代碼文件和代碼行,開發根據人均事件量級進行監控報警功能。

測試階段:

務必和測試溝通,並讓測試在完全理解業務語義的情況下,通過CodeReview和埋點測試兩種方式對埋點正確性進行驗證。

舉例:

比如針對商品購買按鈕埋點,需要檢查埋點測試中上傳數據中事件ID、屬性是否符合定義,另外觸發時機是否正確。

如何落地:

規定如果未經測試的埋點不允許上報埋點數據。

開發什麽功能:

提供所見即所得的埋點測試平臺。

驗收階段:

確保相關人員在完全理解業務語義的情況下,可以通過與自比較和他比較的方式來進行驗證。

舉例:

  • 自比較驗證:同一APP某一個業務線的購買冒泡數量一定要小於所有業務線的冒泡數合計;
  • 他比較驗證:前端某業務點數量和對應服務端數據應該基本相當。

如何落地:

規定如果未經驗證的埋點不允許上報埋點數據。

開發什麽功能:

提供埋點實時數據查詢。

清理階段:

確認完全理解語義的情況下,可對業務發生巨大變化或者不在維護的埋點進行廢棄。

舉例:

百度糯米合並餓了麽後,埋點在經歷產品大改版後已經和其他業務線合並,需要廢棄之前的遺留埋點。

如何落地:

3個月以上未被使用的埋點、1個月以上數據為0的埋點自動廢棄。3個月後使用次日會自動開啟采集。

開發什麽功能:

根據規則提供針對未使用埋點的計算、並自動廢棄。

可以看出,規範要落地,需要整個公司的共識,也需要從上而下的壓力,還有強勢的制度。比如針對全公司個部門做評分,評分規則基於埋點和數據分析抽象出來。


另外我們在前端埋點中也遇到過一些註意事項,整理如下,希望對大家有所幫助。

註意事項:

一些埋點安全性問題:

如果你使用普通的http 協議,在數據傳輸的過程存在被劫持(包括不限於:JS代碼註入等)的可能性,造成H5頁面中出現諸如:未知的廣告或者原網頁被重定向等問題。為了降低此類事件發生的可能性,建議最好使用https 協議(倡導全站https),以確保數據傳輸過程的完整性,安全性。

版本叠代的時候埋點需要註意什麽?

  • 如果是公用模塊,可以非常放心安全的全量遷移埋點;
  • 如果是新增模塊,那就需要註意是否遵循了最新的埋點規範,有沒有重復的埋點命名存在,埋點是否符合業務邏輯;
  • 如果是下線模塊,那就需要評估下線後對數據的影響範圍,而且要第一時間充分周知相關方,讓各方參與評估;
  • 如果是更新模塊,需要評估在原有埋點上需要修改的埋點內容,是否需要重新埋點,刪除不需要的埋點,而且要修改功能的數據承接。

關於埋點上報的解決方案

一般會實現上個模塊,Event收集器,Event緩存器,和Event上報器。

Event上報模式

除了用戶個人不希望耗費流量以外,也可能會因為弱網及斷網情況,如果確保數據不丟失,基於這些問題而誕生的上傳策略,來設計如何上報已收集的所有事件數據。上報一般包括針對內存實時數據的上報和本地持久化數據上報兩個部分,分別介紹一下它們的上報策略與實現方式:

內存埋點數據的實時上報

針對內存埋點數據的上報策略一般如下:

  1. 基於時間間隔:每隔 n秒(時間間隔可以根據公司的業務情況自定義)
  2. 基於數據條數:每累積 n條數據(條數可以自定義)
  3. 不間斷實時上報,如果是低頻率,數據量小,實時性要求高的數據可以不設限制

上述條件滿足時,便會觸發從內存中讀取數據,並執行上傳操作。Native可以創建了一個並發隊列,H5會基於瀏覽器並發發送。

本地持久化數據的延遲上報

為了盡早的上傳本地持久化埋點數據,以防用戶卸載 App或者關閉瀏覽器造成本地數據的丟失,針對本地持久化數據的上傳策略如下:

Native相關:

  1. App 冷啟動
  2. App 進入前臺
  3. App入後臺

HTML5、Hybrid相關:

  1. localstorage,瀏覽器關閉埋點數據並不會被刪除,如果用戶再次訪問,會啟動上報
  2. 基於Native提供的bridge,讓Native幫忙持久化數據,並在再次進入時,啟動上報

這裏也可以創建一個單獨的串行隊列,來實現對本地持久化數據的逐個上報。

本文轉自:https://www.imooc.com/article/27151


(轉)前端埋點的那些事