為什麼你統計 PV 的方式是錯的?

王仕軍發表於2019-03-04

翻譯自 Google 工程師 Philip Walton 的文章。共 3754 字,讀完需 7 分鐘。合格的工程師要能認識到資料和功能一樣重要,因為準確的資料收集是產品迭代、市場營銷的決策基礎。本文會幫你剖析為什麼你常用的統計方式是錯的?然後給出可行的解決方案。

直言不諱的說,目前市面上的 Page View(常說的PV,即使用者瀏覽頁面的次數)統計工具無法準確統計越來越多的新站點,且已經和 WEB 技術的演進方向完全脫節。

因為在大多數情況下,這些工具假設每次頁面瀏覽(Page View)對應一次頁面載入(Page Load),且每次頁面載入完成後都會執行一些統計程式碼,將 Page View 事件傳送到後端伺服器。任何不符合這種模式的網站都需要工程師做額外的工作才能統計到正確的結果,然而大多數前端工程師似乎不具備這方面的專業知識,或者乾脆沒有時間。

現實是,WEB 技術在過去 10 年間發生了巨大的變化,越來越多的網站已經不符合傳統的網站模式,而我們的分析工具演化並沒有跟上。

問題在哪兒?

舉個具體的例子,考慮 mail.google.com(Gmail),使用 Gmail 的大多數人在首次開啟後會保持它在後臺執行,每隔一段時間去檢查是否有新訊息,如果有新訊息,會直接開啟閱讀,整個過程無需重新整理頁面。

由於絕大多數 Gmail 使用者幾乎從來不重新整理頁面,從統計分析的角度就產生了一些非常有趣但重要的疑問:

  • 如果使用者開啟 Gmail 一次,而在接下來的幾天之內使用數百次,但是並沒有重新整理頁面,這種情況應該只算一個 Page View 麼?
  • 如果使用者點選 Gmail 左上角的 Logo 來重新整理頁面內容,或者移動端的下拉重新整理,是否應該算一個新的 Page View?這種動作與完全重新整理頁面有何不同?
  • 如果使用者開啟並閱讀一封新郵件,實際上無需重新整理頁面,是否應該計算為一個新的 Page View?
  • 如果兩個使用者每天訪問 Gmail 的次數完全相同,但是其中一個每次重新整理,而另一個保持頁面在後臺執行,這兩種使用模式的 Page View 統計結果應該有很大的不同麼?

列舉這些疑問想說明的問題是,對於某些站點,繼續使用傳統的 Page View 統計方法會導致不準確的統計結果,而在 WEB 應用的技術實現方案隨時間推移不斷演進的情況下,這種不準確會變的非常離譜。

試想,你在傳統的 WEB 網站中新增了統計程式碼,幾個月後,你將該網站更新為單頁應用(SPA,或 Single Page Application),而沒有修改統計程式碼程式碼。再過幾個月,你又將網站更新為漸進式 WEB 應用(PWA,或 Progressive Web Application),這種技術可以在後臺重新載入內容並離線工作),這時候你仍然沒有更新統計程式碼。如果這段時間應用的訪客數量及使用模式沒有變化,你肯定會期望統計結果不出現大幅度波動。

不幸的是,在上述情況下,即使你改善了使用者體驗,但 Page View 的統計結果可以肯定是下降的。這是一個非常糟糕的情況:你希望改善網站的互動體驗,但是無法用資料說服任何人這樣做是值得的,因為統計資料給出的結果是完全相反的。

該怎麼解決?

任何技術問題總會有解決辦法,本文提出的解決方案則需要回歸 Page View 這個指標的本原。我們需要追蹤的不是頁面被載入(loaded)的次數,而是被瀏覽(viewed)的次數。

我們可以利用 Page Visibility API 達成目的,實際上該 API 已經存在了很長時間,並且幾乎所有的主流桌面和移動瀏覽器都支援

事實證明,統計頁面被瀏覽的次數而不是被載入的次數能優雅地解決掉傳統統計方式不能處理的很多問題:

  • 當使用者開啟的某個選項卡轉入後臺,然後在幾小時或幾天之後再切回來,但不重新載入頁面;
  • 當使用者開啟某個頁面作為參考,並來回切換以快速瀏覽其中的內容,但不重新載入頁面;
  • 當使用者在後臺選項卡中開啟頁面,然後忘記了,從來沒有實際瀏覽頁面內容;

Page Visibility API 由 document.visibilityState 屬性以及 visibilitychange 事件組成。基於這兩個 API,你可以確保只會在頁面的 visibilityState 可見時才傳送 Page View 統計。此外,你還可以監聽 visibilitychange 事件,在使用者重新切回到在後臺執行有段時間的應用時傳送新的 Page View 統計。Page Visibility API 很好的解決了載入完成後幾乎不需要重新整理的 WEB 應用的 Page View 統計問題。

解決方案的第二部分是 History API,這是 SPA 應用構建的基礎技術,目前主流瀏覽器都支援(詳見),因此統計工具可以通過監聽 URL 變化來傳送類似於傳統網站的頁面統計。

該怎麼實現?

利用 Page Visibility 和 History API 來準確統計 Page View 的基本思路如下(這種思路適用於傳統網站、SPA、PWA):

  1. 頁面載入時,如果頁面的 visibilityState 是可見的,傳送 Page View 統計;
  2. 如果頁面的 visibilityState 是隱藏的,就監聽 visibilitychange 事件,並在 visibilityState 變為可見時傳送 Page View 統計;
  3. 如果 visibilityState 由隱藏變為可見,並且自上次使用者互動之後已經過了“足夠長”的時間,就傳送新的 Page View 統計;
  4. 如果 URL 發生變化(僅限於 pathnamesearch 部分傳送變化, hash 部分則應該忽略,因為它是用來標記頁面內跳轉的) 傳送新的 Page View 統計;

上述步驟 3 是最重要的,但同時也是最模糊的和頗具爭議的,關鍵的問題是:究竟多長才算是“足夠長”?一方面,你可能並不想在每次 visibilityState 發生變化的時候都傳送新的 Page View 統計,因為對於使用者來說,在選項卡之間來回切換是非常常見的,而實際情況是,某些應用同時在多個選項卡中開啟使用是最方便的,而這就伴隨這大量的選項卡切換。另一方面,你又期望統計到在一段時間沒有和應用互動之後使用者的回訪(returning)行為,也就是說需要統計到使用者多次使用的行為。

幸運的是,所有的統計工具都定義了一種區分多次使用的方式,即會話,或者叫 Session。會話是在給定時間視窗中發生的使用者互動的集合,當某個預設的時間段過去時會話就結束了。比如,預設情況下 Google Analytics 的會話在 30 分鐘無互動的情況下結束。而大多數統計工具都提供了會話時長自定義的功能。

所以回到上面列表中的第三步,我的建議是,如果使用者會話已結束,並且頁面的 visibilityState 從隱藏變為可見,則應傳送新的 Page View 統計。在會話內發生的 visibilityState 變更不應被視為不同的 Page View。

注意:如果你使用 autotrack(特別是 pageVisibilityTrackerurlChangeTracker 外掛),你就無需自己實現上面的邏輯。這些外掛可以自動處理所有這些情況,當然你可以使用配置項來自定義外掛的行為)。

如何減少誤報?

在為 autotrack 建立 pageVisibilityTracker 外掛時,我對基於 Page Visibility API 的多種實現方案進行了大量徹底的測試,發現利用啟發式資訊在避免誤報上是非常必要的。

例如,使用者使用鍵盤快速在一堆開啟的標籤頁中來回切換,結果是很多頁面的 visibilityState 從隱藏變為可見,但是很快又恢復原狀。在我的測試中,有相當比例的 Page View 是由於在會話超時後 visibilityState 變為可見導致,但是緊接著 visibilityState 又恢復為隱藏。而 99% 類似這種的頁面從可見恢復為隱藏狀態的間隔都在 5 秒以內。

當我分析自己的使用模式之後,這種現象的存在並不奇怪,很常見的操作有:意外的切換到一個選項卡,但是很快就離開了;切換到一個選項卡,只因為我要切換到其他的選項卡,而這個選項卡剛好在夾在中間(這裡使用鍵盤切換);切換到某個選項卡,只是為了關閉它。在所有這些情況下,傳送新的 Page View 並沒有任何意義,而在上報 Page View 統計之前設定 5 秒的超時可以防止 99% 以上的誤報。

Page View 和 Page Load

有時候你可能想了解你的網站載入(Page Load)了但從未被瀏覽過的頻率,你可能還想知道頁面瀏覽是由初始頁面載入觸發還是由 visibilityState 或 URL 變化導致的。

顯然你可以建立一個自定義維度來統計頁面載入(實際上我通常會這樣做),但是透過這個問題我們能清楚的認識到,我們真正需要的是兩個獨立的指標:頁面瀏覽(Page View)頁面載入(Page Load)。幸運的是,如今的大多數統計工具允許使用者自定義指標來統計他們想要的任何資料,而 autotrack 支援通過配置項 幫你把頁面瀏覽與頁面載入的統計分開。

通過將頁面瀏覽與頁面載入解耦,我們就能完全掌握 Page View 這個指標的真實含義:測量使用者實際瀏覽頁面的次數,而無論頁面載入了多少次。

Page View 和 Session

有些讀者可能會嘀咕:只要你正確的統計到了初次頁面載入後使用者的所有互動,只統計首次頁面載入又有什麼關係呢?Page View 的正確統計為什麼至關重要呢?

雖然看起來似乎是一個合理的問題,但如果你瞭解大多數統計工具使用的資料模型,你將很快意識到這些問題本身是站不住腳的。

大多數分析工具假定每個會話都至少包含一個 Page View,該 Page View 用於確定諸如 Landing Page(落地頁)和 Exits(跳出頁)等指標。如果你僅僅統計了初次頁面載入,然後後續所有會話只包含事件統計,則大多數會話報告變得一團糟。而幾乎所有的傳統 WEB 統計工具都使用這種模型來計算,這也從側面印證了傳統模型的侷限性。

暫且把工具限制放在一邊,另外一個讓你信服的論據是:所有包含了使用者互動事件的會話都應該至少包含一次 Page View,畢竟,如果沒有開啟頁面,你怎麼跟它互動呢?在會話超時、visibilityState 變為可見時傳送新的 Page View 能好好的解決這個問題。

總結和 TIPS

希望你讀完這篇文章,能重新思考 Page View 的正確姿勢,如果你在自己專案中使用了統計工具,可以結合本文的建議把統計做到準確。

統計工具應該衡量的是使用者參與度,而不應該與網站的技術實現相耦合。當使用者體驗改善時,我們應該可以通過統計工具的分析報告來證明。這是利用技術推動業務發展最直接的方法。

如果你使用的是 Google Analytics,則可以通過使用 autotrack(強烈建議 SPA 或 PWA 專案使用)來將本文的解決方案運用到專案中,要檢視如何配置 autotrack 的示例?請移步 analyticsjs-boilerplate 倉庫。

One More Thing

本文譯者王仕軍,商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。如果你覺得本文對你有幫助,請點贊!如果對文中的內容有任何疑問,歡迎留言討論。想知道我接下來會寫些什麼?歡迎訂閱知乎專欄:《前端週刊:讓你在前端領域跟上時代的腳步》

相關文章