成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

如何通過(guò)Vue自定義指令實(shí)現(xiàn)前端埋點(diǎn)詳析

3403771864 / 2246人閱讀

  獲取用戶(hù)的交互習(xí)慣及喜好,進(jìn)一步提升轉(zhuǎn)化率,可以在之前的埋點(diǎn)方案實(shí)現(xiàn)中,都是在具體的按鈕或者圖片被點(diǎn)擊或者被曝光時(shí)主動(dòng)通過(guò)事件去上報(bào)埋點(diǎn)。但這種方法適合在埋點(diǎn)比較少時(shí)還行的項(xiàng)目,遇見(jiàn)項(xiàng)目中需要大量埋點(diǎn)時(shí),添加的代碼就太多了,就會(huì)埋點(diǎn)邏輯與業(yè)務(wù)邏輯的高耦合。

  由此需要換種方式。我先給大家普及下埋點(diǎn)上報(bào)方式都有哪些?

  手動(dòng)埋點(diǎn)

  可視化埋點(diǎn)

  無(wú)痕埋點(diǎn)

  手動(dòng)埋點(diǎn),顧名思義就是純手動(dòng)寫(xiě)代碼,調(diào)用埋點(diǎn) SDK 提供的函數(shù),在需要埋點(diǎn)的業(yè)務(wù)邏輯中添加對(duì)應(yīng)方法,上報(bào)埋點(diǎn)數(shù)據(jù)。這種也是之前一直在使用的方法。

  可視化埋點(diǎn)是指通過(guò)可視化系統(tǒng)配置埋點(diǎn),這種方式接觸的不是很多,就不展開(kāi)說(shuō)了。

  無(wú)痕埋點(diǎn),也叫自動(dòng)埋點(diǎn)、全埋點(diǎn)。即對(duì)全局所有事件和頁(yè)面加載周期進(jìn)行攔截埋點(diǎn)。

  一般對(duì)哪些數(shù)據(jù)做埋點(diǎn)?

  為了達(dá)到數(shù)據(jù)分析,便于后續(xù)的運(yùn)營(yíng)及產(chǎn)品策略調(diào)整的目的,一般需要對(duì)以下幾點(diǎn)做埋點(diǎn)統(tǒng)計(jì):

  頁(yè)面埋點(diǎn):統(tǒng)計(jì)用戶(hù)進(jìn)入或者離開(kāi)頁(yè)面的信息,如頁(yè)面瀏覽次數(shù)(pv)、瀏覽頁(yè)面人數(shù)(uv)、頁(yè)面停留時(shí)長(zhǎng)、設(shè)備信息等

  點(diǎn)擊埋點(diǎn):統(tǒng)計(jì)用戶(hù)在頁(yè)面瀏覽過(guò)程中觸發(fā)的點(diǎn)擊事件,如按鈕、導(dǎo)航或者圖片的點(diǎn)擊次數(shù)

  曝光埋點(diǎn):統(tǒng)計(jì)具體元素是否得到有效曝光

  需求分析

  添加埋點(diǎn)的理想化方案是:

  1、埋點(diǎn)與業(yè)務(wù)盡量分離清楚,兩個(gè)業(yè)務(wù)獨(dú)立

  2、減少不對(duì)業(yè)務(wù)代碼有侵入

  3、簡(jiǎn)約規(guī)范,收口要統(tǒng)一處理埋點(diǎn)邏輯

  由于項(xiàng)目是Vue開(kāi)發(fā)的,所以考慮使用自定義指令的方式來(lái)完成埋點(diǎn)上報(bào)。為什么會(huì)選擇自定義指令是為能讓業(yè)務(wù)和埋點(diǎn)解耦。

  頁(yè)面埋點(diǎn)框架搭建好,現(xiàn)在主要是點(diǎn)擊埋點(diǎn)和曝光埋點(diǎn)。

  實(shí)現(xiàn)思路:簡(jiǎn)單來(lái)說(shuō)就是在需要埋點(diǎn)的DOM節(jié)點(diǎn)掛載特殊屬性,通過(guò)埋點(diǎn)SDK監(jiān)聽(tīng)掛載了相應(yīng)屬性對(duì)應(yīng)的事件,造成事件觸發(fā)時(shí)進(jìn)行埋點(diǎn)數(shù)據(jù)上報(bào)。

  那如何監(jiān)聽(tīng)?

  對(duì)于點(diǎn)擊事件,我們可以采用addEventListener來(lái)監(jiān)聽(tīng)click事件。這很簡(jiǎn)單。

  對(duì)于元素的曝光就稍微有點(diǎn)麻煩了。

  首先我們來(lái)看一下為什么需要監(jiān)測(cè)曝光:

  還需增加衡量用戶(hù)對(duì)產(chǎn)品的興趣程度,需要統(tǒng)計(jì)計(jì)算區(qū)域的點(diǎn)擊率(點(diǎn)擊次數(shù)/曝光次數(shù)),要考慮到點(diǎn)擊率的準(zhǔn)確性,保證用戶(hù)真正的瀏覽到了這些產(chǎn)品才可以。

  那么怎么判斷元素出現(xiàn)在頁(yè)面的可視區(qū)域呢?

  以往的思路:監(jiān)聽(tīng)滾動(dòng)事件就是通過(guò)getBoundingClientRect()方法計(jì)算監(jiān)測(cè)區(qū)域與視窗的位置,然后判斷出元素是否出現(xiàn)在頁(yè)面的可視區(qū)域內(nèi)。可由于scroll事件的頻繁觸發(fā),實(shí)可能性很大。

  基于此,瀏覽器特意為我們打造了一個(gè)Intersection ObserverAPI,把性能相關(guān)的細(xì)節(jié)都處理掉,讓開(kāi)發(fā)者只關(guān)心業(yè)務(wù)邏輯即可:

  由于用戶(hù)瀏覽頁(yè)面的不確定性,還必須要避免重復(fù)的曝光行為。這個(gè)在曝光之后,移除觀察即可。

  代碼實(shí)現(xiàn)

  上面的需求分析還是比較抽象,下面讓我們結(jié)合代碼來(lái)看一下最終的實(shí)現(xiàn)。

  Click 類(lèi)封裝

  點(diǎn)擊事件的處理相對(duì)比較簡(jiǎn)單,每次點(diǎn)擊觸發(fā)數(shù)據(jù)上報(bào)即可:

  // src/directives/track/click.js
  import { sendUBT } from "../../utils/ctrip"
  export default class Click {
  add(entry) {
  // console.log("entry", entry);
  const traceVal = entry.el.attributes["track-params"].value
  const traceKey = entry.el.attributes["trace-key"].value
  const { clickAction, detail } = JSON.parse(traceVal)
  const data = {
  action: clickAction,
  detail,
  }
  entry.el.addEventListener("click", function() {
  console.log("上報(bào)點(diǎn)擊埋點(diǎn)", JSON.parse(traceVal))
  console.log("埋點(diǎn)key", traceKey)
  sendUBT(traceKey, data)
  })
  }
  }

  Exposure 類(lèi)封裝

  曝光的相對(duì)復(fù)雜一些。

  首先通過(guò)new IntersectionObserver()實(shí)例化一個(gè)全局_observer,如果得到有效曝光的(這里當(dāng)元素出現(xiàn)一半以上則進(jìn)行曝光),就去獲取 DOM 節(jié)點(diǎn)上的trace-key(埋點(diǎn) key)和track-params(埋點(diǎn) value)。

  // src/directives/track/exposure.js
  import "intersection-observer"
  import { sendUBT } from "../../utils/ctrip"
  // 節(jié)流時(shí)間調(diào)整,默認(rèn)100ms
  IntersectionObserver.prototype["THROTTLE_TIMEOUT"] = 300
  export default class Exposure {
  constructor() {
  this._observer = null
  this.init()
  }
  init() {
  const self = this
  // 實(shí)例化監(jiān)聽(tīng)
  this._observer = new IntersectionObserver(
  function(entries, observer) {
  entries.forEach((entry) => {
  // 出現(xiàn)在視窗內(nèi)
  if (entry.isIntersecting) {
  // 獲取參數(shù)
  // console.log("埋點(diǎn)節(jié)點(diǎn)", entry.target.attributes);
  const traceKey = entry.target.attributes["trace-key"].value
  const traceVal = entry.target.attributes["track-params"].value
  console.log("traceKey", traceKey)
  console.log("traceVal", traceVal)
  const { exposureAction, detail } = JSON.parse(traceVal)
  const data = {
  action: exposureAction,
  detail,
  }
  // 曝光之后取消觀察
  self._observer.unobserve(entry.target)
  self.track(traceKey, data)
  }
  })
  },
  {
  root: null,
  rootMargin: "0px",
  threshold: 0.5, // 元素出現(xiàn)面積,0 - 1,這里當(dāng)元素出現(xiàn)一半以上則進(jìn)行曝光
  }
  )
  }
  /**
  * 元素添加監(jiān)聽(tīng)
  *
  * @param {*} entry
  * @memberof Exposure
  */
  add(entry) {
  this._observer && this._observer.observe(entry.el)
  }
  /**
  * 埋點(diǎn)上報(bào)
  *
  * @memberof Exposure
  */
  track(traceKey, traceVal) {
  // console.log("曝光埋點(diǎn)", traceKey, JSON.parse(traceVal));
  sendUBT(traceKey, traceVal)
  }
  }

  指令封裝

  有了點(diǎn)擊和曝光類(lèi),下一步就是 Vue 指令的封裝了,也是之所以能實(shí)現(xiàn)半自動(dòng)埋點(diǎn)的核心。

  這里存在一個(gè)場(chǎng)景就是對(duì)于同一個(gè)按鈕或者圖片,同時(shí)存在既需要點(diǎn)擊埋點(diǎn)又需要曝光埋點(diǎn)的場(chǎng)景。所以在指令的設(shè)計(jì)時(shí)支持了多帶帶傳入和同時(shí)傳入的場(chǎng)景:

  v-track:click|exposure

  v-track:exposure


  // src/directives/track/index.js
  import Vue from "vue"
  import Click from "./click"
  import Exposure from "./exposure"
  // 實(shí)例化曝光和點(diǎn)擊
  const exp = new Exposure()
  const cli = new Click()
  Vue.directive("track", {
  bind(el, binding) {
  // 獲取指令參數(shù)
  const { arg } = binding
  arg.split("|").forEach((item) => {
  // 點(diǎn)擊
  if (item === "click") {
  cli.add({ el })
  } else if (item === "exposure") {
  exp.add({ el })
  }
  })
  },
  })

  同時(shí)需要在src/index.js引入即可:

  1

  import "./directives/track"

  使用

  在需要埋點(diǎn)的地方使用也是很簡(jiǎn)單的:

  <img
  ref="imageDom"
  trace-key="o_img"
  v-track:click|exposure
  :track-params="
  JSON.stringify({
  exposureAction: 's_pictures',
  clickAction: 'c_pictures',
  detail: {
  value: '測(cè)試',
  },
  })
  "
  />

  不足

  Vue自定義指令只是一個(gè)簡(jiǎn)單封裝,業(yè)務(wù)代碼和埋點(diǎn)代碼達(dá)到解耦程度,這樣埋點(diǎn)的開(kāi)發(fā)成本還是維護(hù)成本都降低了很多。

  現(xiàn)在還有三個(gè)問(wèn)題:曝光時(shí)頻次很高,是否可以考慮批量上報(bào)?用戶(hù)訪問(wèn)一半頁(yè)面,突然切出,之后又重新進(jìn)入,這種情況埋點(diǎn)又該如何上報(bào)?用戶(hù)設(shè)備不支持Intersection ObserverAPI 情況,是否要考慮向下兼容?

  其實(shí)方式方法都在不斷的優(yōu)化中,相信可以有更多完美的優(yōu)化。


文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/127720.html

相關(guān)文章

  • Vue項(xiàng)目代碼埋點(diǎn)

    摘要:主流埋點(diǎn)方案目前主流的埋點(diǎn)方案包括代碼埋點(diǎn)可視化埋點(diǎn)無(wú)埋點(diǎn)一代碼埋點(diǎn)在需要埋點(diǎn)的節(jié)點(diǎn)調(diào)用接口,攜帶數(shù)據(jù)上傳。二可視化埋點(diǎn)通過(guò)可視化交互的手段,代替代碼埋點(diǎn)。也就是用一個(gè)系統(tǒng)來(lái)實(shí)現(xiàn)手動(dòng)插入代碼埋點(diǎn)的過(guò)程。 主流埋點(diǎn)方案 目前主流的埋點(diǎn)方案包括 代碼埋點(diǎn) 可視化埋點(diǎn) 無(wú)埋點(diǎn) 一、代碼埋點(diǎn) ? 在需要埋點(diǎn)的節(jié)點(diǎn)調(diào)用接口,攜帶數(shù)據(jù)上傳。如百度統(tǒng)計(jì)等; ? 缺點(diǎn) ? 工作量...

    anRui 評(píng)論0 收藏0
  • Vue項(xiàng)目代碼埋點(diǎn)

    摘要:主流埋點(diǎn)方案目前主流的埋點(diǎn)方案包括代碼埋點(diǎn)可視化埋點(diǎn)無(wú)埋點(diǎn)一代碼埋點(diǎn)在需要埋點(diǎn)的節(jié)點(diǎn)調(diào)用接口,攜帶數(shù)據(jù)上傳。二可視化埋點(diǎn)通過(guò)可視化交互的手段,代替代碼埋點(diǎn)。也就是用一個(gè)系統(tǒng)來(lái)實(shí)現(xiàn)手動(dòng)插入代碼埋點(diǎn)的過(guò)程。 主流埋點(diǎn)方案 目前主流的埋點(diǎn)方案包括 代碼埋點(diǎn) 可視化埋點(diǎn) 無(wú)埋點(diǎn) 一、代碼埋點(diǎn) ? 在需要埋點(diǎn)的節(jié)點(diǎn)調(diào)用接口,攜帶數(shù)據(jù)上傳。如百度統(tǒng)計(jì)等; ? 缺點(diǎn) ? 工作量...

    canger 評(píng)論0 收藏0
  • vue2.0 項(xiàng)目開(kāi)發(fā)小結(jié)

    摘要:項(xiàng)目架構(gòu)項(xiàng)目目錄項(xiàng)目目錄是采用自動(dòng)生成,其它按需自己新建就好了。 項(xiàng)目架構(gòu) 項(xiàng)目目錄 ├── build ├── config ├── dist │?? └── static │?? ├── css │?? ├── fonts │?? ├── images │?? ├── js │?? └── lib ├── src │?? ├── api │?...

    yagami 評(píng)論0 收藏0
  • vue2.0 項(xiàng)目開(kāi)發(fā)小結(jié)

    摘要:項(xiàng)目架構(gòu)項(xiàng)目目錄項(xiàng)目目錄是采用自動(dòng)生成,其它按需自己新建就好了。 項(xiàng)目架構(gòu) 項(xiàng)目目錄 ├── build ├── config ├── dist │?? └── static │?? ├── css │?? ├── fonts │?? ├── images │?? ├── js │?? └── lib ├── src │?? ├── api │?...

    wuyangnju 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<