首頁  >  文章  >  web前端  >  前端怎麼埋點?淺析vue自訂指令進行前端埋點的方法

前端怎麼埋點?淺析vue自訂指令進行前端埋點的方法

青灯夜游
青灯夜游轉載
2022-07-14 20:44:024895瀏覽

怎麼進行前端埋點?以下這篇文章跟大家介紹一下怎麼透過Vue自訂指令實現前端埋點,希望對大家有幫助!

前端怎麼埋點?淺析vue自訂指令進行前端埋點的方法

(學習影片分享:vue影片教學

在行銷活動中,透過埋點可以取得使用者的喜好及互動習慣,進而優化流程,進一步提升使用者體驗,提升轉換率。

在先前的埋點方案實作中,都是在具體的按鈕或圖片被點擊或是被曝光時主動透過事件去上報埋點。這種方法在專案中埋點比較少時還行,一旦專案中需要大量埋點時,不可避免的要增加許多業務程式碼。也很大程度造成了埋點邏輯與業務邏輯的高耦合。

為了改造這個情況,我們對於原有的埋點方式做了一些小改進,使得埋點效率得到了極大提升。

在闡述我們的埋點改造之前,有必要對埋點的一些常識做下簡單的了解。

埋點上報方式都有哪些?

要知道埋點的類型很多,上報的方式也是五花八門。前端常見的埋點方法有三種:

  • 手動埋點
  • 可視化埋點
  • 無痕埋點

手動埋點,顧名思義就是純手動寫程式碼,呼叫埋點SDK 提供的函數,在需要埋點的業務邏輯中加入對應方法,上報埋點資料。這種也是之前一直在使用的方法。

視覺化埋點是指透過視覺化系統配置埋點,這種方式接觸的不是很多,就不展開說了。

無痕埋點,也叫自動埋點、全埋點。即對全域所有事件和頁面載入週期進行攔截埋點。

一般對哪些資料做埋點?

為了達到資料分析,便於後續的營運及產品策略調整的目的,一般需要對以下幾點做埋點統計:

  • 頁埋:統計使用者進入或離開頁面的訊息,如頁面瀏覽次數(pv)、瀏覽頁面人數(uv)、頁面停留時間、裝置資訊等
  • 點擊埋點:統計使用者在頁面瀏覽過程中觸發的點擊事件,如按鈕、導航或圖片的點擊次數
  • 曝光埋點:統計具體元素是否有效曝光

需求分析

#本文是基於最近專案中添加埋點的需求,我們需要的一種理想化方案是:

  • #埋點與業務盡量分離,埋點邏輯更應該是獨立於業務的
  • 盡量不對業務代碼有侵入
  • 約定規範,透過統一收口來處理埋點邏輯

由於專案是Vue開發的,所以考慮使用自訂指令的方式來完成埋點上報。選擇自訂指令的原因也是因為他能一定程度上能讓業務和埋點解耦。

頁面埋點在框架層面已經幫我們做掉了,這裡主要關心的是點擊埋點和曝光埋點。

實現想法其實也很清晰:在需要埋點的DOM節點掛載特殊屬性,透過埋點SDK監聽掛載了對應屬性對應的事件,在事件觸發時進行埋點資料回報。

那麼問題來了,怎麼監聽呢?

對於點擊事件,我們可以採用addEventListener來監聽click事件。這很簡單。

對於元素的曝光就稍微有點麻煩了。

首先我們來看看為什麼需要監控曝光:

前端怎麼埋點?淺析vue自訂指令進行前端埋點的方法

為了衡量使用者對產品的興趣程度,需要計算區域的點擊率(點擊次數/曝光次數)。為了確保點擊率的準確性,我們必須確保用戶真正的瀏覽到了這些產品(就比如上圖中最下方的機酒產品區域,由於需要滾動頁面,用戶才有可能看到這一區域)。

那麼要怎麼判斷元素出現在頁面的視覺區域呢?

依照以往的做法:監聽捲動事件,透過getBoundingClientRect()方法計算監控區域與視窗的位置,然後判斷元素是否出現在頁面的視覺區域內。但是由於scroll事件的頻繁觸發,性能問題很大。

基於此,瀏覽器特意為我們打造了一個Intersection ObserverAPI,把效能相關的細節都處理掉,讓開發者只關心業務邏輯即可:

前端怎麼埋點?淺析vue自訂指令進行前端埋點的方法

由於使用者瀏覽頁面的不確定性,也必須避免重複的曝光行為。這個在曝光之後,移除觀察即可。

程式碼實作

上面的需求分析還是比較抽象,以下讓我們結合程式碼來看一下最終的實作。

Click 類別封裝

點擊事件的處理相對比較簡單,每次點擊觸發資料回報即可:

// 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("上报点击埋点", JSON.parse(traceVal))
      console.log("埋点key", traceKey)
      sendUBT(traceKey, data)
    })
  }
}

Exposure 類封裝

曝光的相對複雜。

首先透過new IntersectionObserver() 實例化一個全域_observer,如果得到有效曝光的(這裡當元素出現一半以上則進行曝光),就去獲取DOM 節點上的trace-key(埋點key)和track-params(埋點value)。

// src/directives/track/exposure.js
import "intersection-observer"
import { sendUBT } from "../../utils/ctrip"

// 节流时间调整,默认100ms
IntersectionObserver.prototype["THROTTLE_TIMEOUT"] = 300

export default class Exposure {
  constructor() {
    this._observer = null
    this.init()
  }

  init() {
    const self = this

    // 实例化监听
    this._observer = new IntersectionObserver(
      function(entries, observer) {
        entries.forEach((entry) => {
          // 出现在视窗内
          if (entry.isIntersecting) {
            // 获取参数
            // console.log("埋点节点", 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, // 元素出现面积,0 - 1,这里当元素出现一半以上则进行曝光
      }
    )
  }

  /**
   * 元素添加监听
   *
   * @param {*} entry
   * @memberof Exposure
   */
  add(entry) {
    this._observer && this._observer.observe(entry.el)
  }

  /**
   * 埋点上报
   *
   * @memberof Exposure
   */
  track(traceKey, traceVal) {
    // console.log("曝光埋点", traceKey, JSON.parse(traceVal));
    sendUBT(traceKey, traceVal)
  }

}

指令封裝

有了點擊和曝光類,下一步就是 Vue 指令的封裝了,也是之所以能實現半自動埋點的核心。

這裡存在一個場景就是對於同一個按鈕或圖片,同時存在著既需要點擊埋點又需要曝光埋點的場景。所以在指令的設計時支援了單獨傳入和同時傳入的場景:

  • v-track:click|exposure
  • v -track:exposure
// src/directives/track/index.js
import Vue from "vue"
import Click from "./click"
import Exposure from "./exposure"

// 实例化曝光和点击
const exp = new Exposure()
const cli = new Click()

Vue.directive("track", {
  bind(el, binding) {
    // 获取指令参数
    const { arg } = binding
    arg.split("|").forEach((item) => {
      // 点击
      if (item === "click") {
        cli.add({ el })
      } else if (item === "exposure") {
        exp.add({ el })
      }
    })
  },
})

同時需要在src/index.js引進即可:

import "./directives/track"

使用

#在需要埋點的地方使用也是很簡單的:

<img
  ref="imageDom"
  trace-key="o_img"
  v-track:click|exposure
  :track-params="
    JSON.stringify({
      exposureAction: &#39;s_pictures&#39;,
      clickAction: &#39;c_pictures&#39;,
      detail: {
        value: &#39;测试&#39;,
      },
    })
  "
/>

不足

透過Vue自訂指令的一個簡單封裝,業務程式碼和埋點程式碼就達到了一定的解耦,相較之前,無論是埋點的開發成本還是維護成本都降低了很多。

但這也只是一個最簡單的實現,還有很多情況要考慮:

  • 曝光時頻次很高,是否可以考慮批次上報?
  • 用戶造訪一半頁面,突然切出,之後又重新進入,這種情況埋點又該如何上報?
  • 使用者裝置不支援Intersection ObserverAPI 情況,是否要考慮向下相容?

#鑑於這套埋藏點方案還在不斷完善中,等後續完善並在業務中落地平穩運行後。我再分享其中的細節給大家。

【相關影片教學推薦:vuejs入門教學web前端入門

以上是前端怎麼埋點?淺析vue自訂指令進行前端埋點的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除