隨着互聯網發展,企業對於網站的PV、UV、用戶的轉化、新增和留存也愈來愈關注。而完整的數據採集是一切的前提。css
埋點即監控用戶在應用表現層的行爲,於產品迭代而言相當重要,運營,產品,數據分析基於此來對用戶行爲進行分析統計,同時埋點也可做爲一種前端監控的手段,檢驗功能是否達預期的佐證。html
基於埋點數據進行用戶行爲分析,能夠獲得包含頁面點擊量、用戶訪問量、用戶訪問路徑、用戶轉化率、導流轉化率、用戶訪問時長和用戶訪問內容分析等重要數據。前端
經過埋點網站訪問來源,能夠統計用戶入口分佈,統計什麼推廣最有效,產品用戶的彙集地方分佈。vue
經過產品功能點擊的埋點,統計知道用戶感興趣的是什麼,便於產品運營更好的更新產品,取消或改進不感興趣的產品。node
地理分佈瀏覽器類型、網站停留時常、尋找產品用戶羣體,針對羣體進行改進更新,以及對其餘羣體進行吸引等等。react
經過訪問頁面的註冊用戶數和頁面 PV 的比值瞭解用戶轉化率。
經過導流頁面PV和源頁面 PV 的比值統計導流轉化率。git
type - 上報類型
appid - 設備id
screen - 屏幕信息
userAgent - 瀏覽器信息
userInfo - 用戶身份信息
timestamp - 上報時間
document.referrer - 訪問來源
action - 上報事件的動做類型
element - 觸發上報的元素
地理位置
訪問渠道
以及其餘自定義數據params等等github
前端埋點大體分爲:代碼埋點、可視化埋點、無痕埋點三種。json
如百度統計、友盟、TalkingData、Google Analytics、Sensors Analytics等都提供了這一方案。
使用相對簡單,在APP或者界面初始化的時候,初始化第三方數據分析服務商的SDK,而後在某個事件發生時就調用SDK裏面相應的數據發送接口發送數據。例如,咱們想統計APP裏面某個按鈕的點擊次數,則在APP的某個按鈕被點擊時,能夠在這個按鈕對應的 OnClick 函數裏面調用SDK提供的數據發送接口來發送數據。後端
除此針對特定需求也能夠統一封裝數據上報通用sdk,各頁面各業務模塊按需調用,同時埋點的形式也是多種多樣的
// 上報sdk export const sdk = { params: null, initParams() { const params={}; params.domain = document.domain || ''; params.title = document.title || ''; params.referrer = document.referrer || ''; params.sw = window.screen.width || 0; params.sh = window.screen.height || 0; params.lang = navigator.language || ''; params.ua = navigator.userAgent || ''; params.loadT = window.performance.timing.domContentLoadedEventEnd - window.performance.timing.navigationStart || 0; params.timestamp= new Date(); sdk.params = params; }, report(params = {}) { // 上報 if(!sdk.params){ sdk.initParams(); } const _params = merge({},sdk.params,params); request('/api/report',{params:_params}); } }; // react wapper組件式 // 封裝埋點包裹組件 export default function TrackerClick(props) { const { children, type } = props; return React.Children.map(children, child => { React.cloneElement(child, { onClick: (e) => { const originClick = child.props.onClick; typeof originClick==='function' && originClick.call(child, e); sdk.dispatch({type}); } }) }); } // 頁面使用 <TrackerClick type="namespace.click"> <Button onClick={handleClick}>查看</Button> </TrackerClick>
// 通用方式 //上報事件的綁定類型對應的綁定名稱 const REPORT_EVENT_FUNC = 'data-reporteventfunc'; //上報事件數據對應的綁定參數名稱 const REPORT_EVENT_DATA = 'data-reporteventdata'; document.body.addEventListener('click',function(e){ if(e.target.getAttribute(REPORT_EVENT_FUNC)==='click'){ const str=e.target.getAttribute(REPORT_EVENT_DATA); sdk.report(JSON.stringify(str)); } }) // 頁面-react <span data-reporteventfunc="click" data-reporteventdata={JSON.stringify({code:1,id:2})}></span> // 頁面-vue <span data-reporteventfunc="click" :data-reporteventdata="JSON.stringify({code:1,id:2})"></span>
// 使用裝飾器,剝離埋點與業務邏輯實現上的耦合,實現低侵入埋點 @tracker((params)=>request('/api/report',{params})) click(params){ // click業務... } const tracker = partical=>(target, key, descriptor)=>{ if (typeof partical!=='function') { throw new Error('tracker arguments is not a function ' + partical) } const oldValue=descriptor.value; descriptor.value=function(...args){ partical.apply(this,args); return oldValue.apply(this,args); } return descriptor; }
// Vue中經過mixin beforeRouteEnter(to, from, next) { this.enterTime=+ new Date(); }, beforeRouteLeave(to, from, next) { sdk.report({ type: 'visit', name: to.name, enterTime: this.enterTime, leaveTime: +new Date(), params: { from: { name: from.name, path: from.path, query: from.query }, to: { name: to.name, path: to.path, query: to.query }, } }) }
傳統基於DOMContentLoaded、beforeunload、onload等也能夠實現
<style> .tracker:active::after{ content: url("http://www.yzw.com/api/tracker/report?action=yourdata"); } </style> <a class="tracker">點擊我,會發埋點數據</a>
埋點數據上報的形式
適用於須要接受數據上報後的返回結果進行回調處理
sdk.report=(params){ // 1.img標籤 var img = document.createElement("img"); img.src = '/api/report?' + querystring.stringify(params); // 2.img對象 const img = new Image(); img.src='/api/report?' + querystring.stringify(params); // 3.script標籤 var script = document.createElement("script"); script.src = src; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script); }
方案有Mixpanel、TalkingData、諸葛IO、騰訊MTA,Sensors AnalyticsV1.3+等
可視化埋點一般流程爲:
輸入頁面的url =>
頁面加載完成後 =>
配置可視化的工具 =>
點擊建立事件(click) =>
進入元素選擇模式 =>
用鼠標點擊頁面上的某個元素(例如button、a這些element)=>
就能夠在彈出的對話框裏面 =>
設置這個事件的名稱(好比叫TEST),選上報數據屬性(properties)=>
保存配置 =>
用戶訪問點擊按鈕 =>
數據上報
其中針對元素標記可能是利用xpath,是在xml文檔中查找信息的語言,以下所示
const getPath = function (elem) { if (elem.id != '') { return '//*[@id="' + elem.id + '"]'; } if (elem == document.body) { return '/html/' + elem.tagName.toLowerCase(); } let index = 1, siblings = elem.parentNode.childNodes; for (const i = 0, len = siblings.length; i < len; i++) { const sibling = siblings[i]; if (sibling === elem) { return arguments.callee(elem.parentNode) + '/' + elem.tagName.toLowerCase() + '[' + (index) + ']'; } else if (sibling.nodeType === 1 && sibling.tagName === elem.tagName) { index++; } } }
經過上述方法,當咱們點擊某個元素時,將觸發的元素event.target傳入,便可獲得完整的xpath。
若是將其換作dom的選擇器,相似:div#container>div:nth-of-type(2)>p:nth-of-type(1),由此,能夠定位到具體的DOM節點
使用者在本身的網頁引入 Sensors Analytics 的 JavaScript SDK 代碼後,從 Sensors Analytics 的後臺可視化埋點管理界面跳轉到使用者的網站界面時,會自動進入到可視化埋點模式。在這個模式下,使用者在網頁上點擊任意 html元素時,Sensors Analytics 都會取到這個元素的url,層級關係等信息來描述這個 html 元素,當使用者設置了這個元素和某個事件相關聯時,SDK 會把這些關聯信息和客戶生成配置信息,而且存放在 Sensors Analytics 提供的相應保存位置。當真正的用戶以普通模式訪問這個網頁時,SDK 會自動加載配置信息,從而在相應的元素被點擊時,使用 Sensors Analytics 的數據發送接口來 track 事件。
從上面咱們介紹的可視化埋點的方案能夠看出,可視化埋點很好地解決了代碼埋點的埋點代價大和更新代價大兩個問題。可是,可視化埋點可以覆蓋的功能有限,目前並非全部的控件操做均可以經過這種方案進行定製;同時,Mixpanel 爲首的可視化埋點方案是不能本身設置屬性的,例如,一個界面上有一個文本框和一個按鈕,經過可視化埋點設置點擊按鈕爲一個「提交」事件時,並不能將文本框的內容做爲事件的屬性進行上傳的,所以,對於可視化埋點這種方案,在上傳事件時,就只能上傳 SDK 自動收集的設備、地域、網絡等默認屬性,以及一些經過代碼設置的全局公共屬性了;最後,做爲前端埋點的一種方案,可視化埋點也依然沒有解決傳輸時效性和數據可靠性的問題。
Heap、百度(點擊猴子)、GrowingIO等
與可視化埋點又相似,兩者的區別就是可視化埋點先經過界面配置哪些控件的操做數據須要收集;「無埋點」則是先儘量收集全部的控件的操做數據,而後再經過界面配置哪些數據須要在系統裏面進行分析。
「無埋點」相比可視化埋點的優勢,一方面是解決了數據「回溯」的問題,例如,在某一天,忽然想增長某個控件的點擊的分析,若是是可視化埋點方案,則只能從這一時刻向後收集數據,而若是是「無埋點」,則從部署 SDK 的時候數據就一直都在收集了;另外一方面,「無埋點」方案也能夠自動獲取不少啓發性的信息,例如,「無埋點」能夠告訴使用者這個界面上每一個控件分別被點擊的機率是多大,哪些控件值得作更進一步的分析等等。
固然,與可視化埋點同樣,「無埋點」依然沒有解決覆蓋的功能優先,不能靈活地自定義屬性,傳輸時效性和數據可靠性欠佳這幾個缺點。甚至因爲全部的控件事件都所有蒐集,反而會給服務器和網絡傳輸帶來更大的負載。
技術實現上也能夠經過攔截全局頁面訪問和事件響應,分析用戶訪問全流程路徑,上報全部觸發埋點,所以無埋點也叫全埋點。
  | 代碼埋點 | 可視化埋點 | 無埋點 |
優勢 | 可控性強,靈活性高,可定製各類特殊埋點需求,監測數據準確。 | 經過集成sdk,運營可自主選擇,操做便捷,知足大部分場景 | 數據全面,不須要關注埋點邏輯,前端開發量輕 |
缺點 | 侵入型強,須要開發手動在相應位置進行埋點,增長維護成本 | 一般須要引入第三方,控件有限,技術上推廣和實現起來有難度,須要運營配合 | 流量和採集的數據過於龐大,存在浪費、服務器性能壓力大、難以特殊化定製 |
適用場景 | 適用於埋點量少、定製化程度高的需求 | 埋點量多,須要對數據深度整合分析 | 網站須要全埋點監控 |
每種方案各有優劣,並不存在某種廣泛完美的能夠適應一切場景的埋點方案,而是應該根據不一樣的產品,不一樣的分析需求,不一樣的系統架構,不一樣的使用場景,選擇最合適的一種接入方案。下面是一些典型的例子: