<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何精確統(tǒng)計頁面停留時長

          共 4302字,需瀏覽 9分鐘

           ·

          2021-01-23 01:27

          來源:今日頭條技術(shù)

          1.背景

          頁面停留時間(Time on Page)簡稱 Tp,是網(wǎng)站分析中很常見的一個指標,用于反映用戶在某些頁面上停留時間的長短,傳統(tǒng)的Tp統(tǒng)計方法會存在一定的統(tǒng)計盲區(qū),比如無法監(jiān)控單頁應用,沒有考慮用戶切換Tab、最小化窗口等操作場景。基于上述背景,重新調(diào)研和實現(xiàn)了精確統(tǒng)計頁面停留時長的方案,需要 兼容單頁應用和多頁應用,并且不耦合或入侵業(yè)務代碼。

          2.分析

          我們可以把一個頁面生命周期抽象為三個動作:「進入」、「活躍狀態(tài)切換」、「離開」


          如下圖,計算頁面停留時長既如何監(jiān)控這三個動作,然后在對應觸發(fā)的事件中記錄時間戳,比如要統(tǒng)計活躍停留時長就把 active 區(qū)間相加即可,要統(tǒng)計總時長既 tn -t0 。

          2.1 如何監(jiān)聽頁面的進入和離開?

          對于常規(guī)頁面的 首次加載、頁面關閉、刷新 等操作都可以通過 window.onload 和 window.onbeforeunload 事件來監(jiān)聽頁面進入和離開,瀏覽器前進后退可以通過 pageshow 和 pagehide 處理。

          • load / beforeunload

          • pageshow / pagehide

          對于單頁應用內(nèi)部的跳轉(zhuǎn)可以轉(zhuǎn)化為兩個問題:

          • 監(jiān)聽路由變化

          • 判斷變化的URL是否為不同頁面 。

          2.1.1 監(jiān)聽路由變化

          目前主流的單頁應用大部分都是基于 browserHistory (history api) 或者 hashHistory 來做路由處理,我們可以通過監(jiān)聽路由變化來判斷頁面是否有可能切換。注意是有可能切換,因為URL發(fā)生變化不代表頁面一定切換,具體的路由配置是由業(yè)務決定的(既URL和頁面的匹配規(guī)則)。

          browserHistory

          路由的變化本質(zhì)都會調(diào)用 History.pushState() 或 History.replaceState() ,能監(jiān)聽到這兩個事件就能知道。通過 popstate 事件能解決一半問題,因為 popstate 只會在瀏覽器前進后退的時候觸發(fā),當調(diào)用 history.pushState() or history.replaceState() 的時候并不會觸發(fā)。

          The popstate event is fired when the active history entry changes. If the history entry being activated was created by a call to history.pushState() or was affected by a call to history.replaceState(), the popstate event’s state property contains a copy of the history entry’s state object.

          Note that just calling history.pushState() or history.replaceState() won’t trigger apopstateevent. The popstate event will be triggered by doing a browser action such as a click on the back or forward button (or calling。history.back() or history.forward() in JavaScript).

          這里需要通過猴子補丁(Monkeypatch)解決,運行時重寫 history.pushState 和 history.replaceState 方法:

          let _wr = ?function (type) { ?
          ?
          let orig = window.history[type]
          ?
          return ?function () {
          ? ?
          let rv = orig.apply(this, arguments)
          ? ?
          let e = new Event(type.toLowerCase())
          ? ?e
          .arguments = arguments
          ? ?window
          .dispatchEvent(e)
          ? ?
          return rv
          ?
          }}
          window
          .history.pushState = _wr('pushState') ?
          window
          .history.replaceState = _wr('replaceState')
          window
          .addEventListener('pushstate', ?function (event) {}) ?
          window
          .addEventListener('replacestate', ?function (event) {})

          hashHistory

          hashHistory 的實現(xiàn)是基于 hash 的變化,hash 的變化可以通過 hashchange 來監(jiān)聽

          2.1.2 判斷URL是否為不同頁面

          方案1: 客戶端定義

          通過業(yè)務方在初始化的時候配置頁面規(guī)則,然后JS通過URL匹配不同的規(guī)則來區(qū)分不同的頁面,這種方案在客戶端數(shù)據(jù)上報的時候就已經(jīng)明確了不同的頁面,偽代碼:

          new Tracer({ ?
          ?rules
          : [
          ? ?
          { path: '/index' },
          ? ?
          { path: '/detail/:id' },
          ? ?
          { path: '/user', query: {tab: 'profile'} }
          ?
          ])

          方案2: 數(shù)據(jù)分析平臺定義

          假設我們最終上報后有一個數(shù)據(jù)分析平臺來展現(xiàn),我們可以在類似數(shù)據(jù)平臺來配置頁面規(guī)則,這樣在客戶端實現(xiàn)的代碼邏輯就不需要區(qū)分頁面,而是每次URL發(fā)生變化就將數(shù)據(jù)上報,最終通過數(shù)據(jù)平臺配置的頁面URL規(guī)則來求和、過濾數(shù)據(jù)等。

          當數(shù)據(jù)展現(xiàn)平臺不支持配置URL規(guī)則來區(qū)分頁面的時候,可以采用方案1;當有數(shù)據(jù)平臺支持的時候采用方案2更合理;

          2.1.3 對于頁面進入和離開相關事件整理

          2.2 如何監(jiān)聽頁面活躍狀態(tài)切換?

          可以通過 Page Visibility API 以及在 window 上聲明 onblur/onfocus 事件來處理。

          2.2.1 Page Visibility API

          一個網(wǎng)頁的可見狀態(tài)可以通過 Page Visibility API 獲取,比如當用戶 切換瀏覽器Tab、最小化窗口、電腦睡眠 的時候,系統(tǒng)API會派發(fā)一個當前頁面可見狀態(tài)變化的 visibilitychange 事件,然后在事件綁定函數(shù)中通過 document.hidden 或者 document.visibilityState 讀取當前狀態(tài)。

          document.addEventListener('visibilitychange', ?function (event) { ?
          ?console
          .log(document.hidden, document.visibilityState)})

          2.2.2 onblur/onfocus

          可以通過 Page Visibility API 以及在 window 上聲明 onblur/onfocus 事件來處理。對于PC端來說,除了監(jiān)聽上述相關事件外,還可以考慮監(jiān)聽鼠標行為,比如當一定時間內(nèi)鼠標沒有操作則認為用戶處于非活躍狀態(tài)。

          2.3 什么時機上報數(shù)據(jù)?

          2.3.1 頁面離開時上報

          對于頁面刷新或者關閉窗口觸發(fā)的操作可能會造成數(shù)據(jù)丟失

          2.3.2 下次打開頁面時上報

          會丟失歷史訪問記錄中的最后一個頁面數(shù)據(jù)

          目前采用的方案2,對于單頁內(nèi)部跳轉(zhuǎn)是即時上報,對于單頁/多頁應用觸發(fā) window.onbeforeunload 事件的時候會把當前頁面數(shù)據(jù)暫存在 localStorage 中,當用戶下次進入頁面的時候會把暫存數(shù)據(jù)上報。有個細節(jié)問題,如果用戶下次打開頁面是在第二天,對于統(tǒng)計當天的活躍時長會有一定的誤差,所以在數(shù)據(jù)上報的同時會把該條數(shù)據(jù)的頁面進入時間/離開時間帶上。

          3.設計

          3.1 UML類關系圖

          Tracer

          核心類,用來實例化一個監(jiān)控,對原生事件和自定義事件的封裝,監(jiān)聽 enter activechange exit 事件來操作當前 Page 實例。

          P.S. 取名來自暴雪旗下游戲守望先鋒英雄獵空(Tracer),直譯為:追蹤者。

          Page
          頁面的抽象類,用來實例化一個頁面,封裝了 enter exit active inactive 等操作,內(nèi)部通過 state 屬性來維護當前頁面狀態(tài)。

          3.2 事件派發(fā)關系圖

          4.兼容性

          Desktop

          Mobile

          5.思考

          對于頁面停留時長的定義可能在不同場景會有差異,比如內(nèi)部業(yè)務系統(tǒng)或者OA系統(tǒng),產(chǎn)品可能更關心用戶在頁面的活躍時長;而對于資訊類型的產(chǎn)品,頁面可見時長會更有價值。單一的數(shù)據(jù)對業(yè)務分析是有限的,所以在具體的代碼實過程中我們會把停留時長分三個指標,這樣能更好的幫助產(chǎn)品/運營分析。

          • active 頁面活躍時長

          • visible 頁面可見時長 //僅支持Desktop

          • duration 頁面總停留時長

          6.參考

          • https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onhashchange

          • https://developer.mozilla.org/en-US/docs/Web/Events/popstate

          • https://developer.mozilla.org/en-US/docs/Web/API/PageVisibilityAPI

          • https://stackoverflow.com/questions/4570093/how-to-get-notified-about-changes-of-the-history-via-history-pushstate

          作者:今日頭條技術(shù)

          https://techblog.toutiao.com/2018/06/05/ru-he-jing-que-tong-ji-ye-mian-ting-liu-shi-chang/

          專注分享當下最實用的前端技術(shù)。關注前端達人,與達人一起學習進步!

          長按關注"前端達人"

          瀏覽 56
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  曰韩三级 | 九九九黄片 | 新疆女人1级毛片 | 四虎成人精品无码永久在线 | 国产精品成人无码久久久 |