爲了更好地瞭解用戶對產品的使用狀況,業務中,咱們常常會收到埋點統計的需求,好比:我要說話前端
不管是移動端仍是 PC 端,相信不少朋友都遇到了這麼幾個十分讓人頭疼的問題:我要說話git
若是咱們把這樣的數據交給了產品同窗,可能會讓他們對用戶行爲產生錯誤的認知,必定程度上影響產品的下一步改善。我要說話github
上面提到的問題,從技術角度能夠概括爲兩點:我要說話編程
針對第一點,機率較小,通常的處理方式就是,不要把統計腳本參合到其餘腳本中,單獨加載,而且放在前頭,讓它優先加載。不少公司的作法是,不讓開發者關心統計腳本的加載,用戶請求頁面的時候,Nginx 會在 Body 開始標籤位置注入一段腳本。我要說話跨域
對於問題二,處理方案就有不少了。我要說話數組
1. 阻塞式的 Ajax 請求我要說話瀏覽器
還記得 XMLHttpRequest::open
方法的第三個參數吧,若是設置爲 false 就是同步加載,我要說話app
window.addEventListener('unload', function(event) { |
阻塞頁面關閉,固然能夠在 readState
爲 2 的時候就 abort 請求,由於咱們不關心響應的內容,只要請求發出去就好了。我要說話異步
2. 暴力的死循環我要說話函數
原理跟上面相似,只不過是使用一個空的死循環阻塞頁面關閉,我要說話
window.addEventListener('unload', function(event) { |
3. 發一個圖片請求阻塞我要說話
大部分瀏覽器都會等待圖片的加載,趁這個機會把統計數據發送出去我要說話
window.addEventListener('unload', function(event) { |
以上提到的幾個方案都是一個原理,讓瀏覽器繼續保持阻塞狀態,等數據發送出去後再跳轉,這裏存在的問題是:我要說話
是否有更好的方案解決這個問題呢,前端同窗秉着「小強精神」也提出了兩個可實踐的方案。我要說話
不就是埋點統計數據嘛,非得在當前頁面發送出去?優化方案的思路具備必定的跳躍性,咱們考慮將數據在下跳頁中發送,那麼問題就轉換爲,如何將數據傳遞給下跳頁?我要說話
對於連接點擊量的統計,咱們能夠將連接信息經過 url 傳遞給下跳頁,傳遞思路以下:我要說話
1. url 傳參我要說話
經過數組標識一個連接的位置信息,如 [站點id,頁面id,模塊id,連接index]
,經過四個參數能夠唯一標識連接位置屬性,使用 URL param 參數將數組數據傳遞給下跳頁,等待由下跳頁將數據發送出去。我要說話
這裏存在的問題是,下跳頁中必須部署一樣的統計腳本,但對一個系統來講,這是很容易作到的。咱們也不會在本身的網頁上放其餘網站的連接吧,因此整個數據的統計都在一個閉環內。我要說話
2. 經過 window.name
傳遞數據我要說話
window.name
是瀏覽器給咱們開放的一個接口,設置該屬性的值後,即使頁面發生了跳轉,這個值依然不會變化,而且能夠跨域使用。我要說話
這裏存在的問題是,該屬性可能被開發者用於其餘途徑。咱們能夠限制開發者直接使用window.name
,封裝接口,經過接口調用,如 aralejs 提供的 nameStorage,我要說話
nameStorage.setItem(key, value); |
儲存形式爲:我要說話
scheme nameStorage datas |
以上雖然基本解決了數據丟失和體驗差的問題,可是這也很大程度依賴於開發者的編程習慣,如不能隨便玩耍 window.name
;也對系統有必定的要求,必須在全部頁面上部署一樣的埋點腳本。我要說話
上面提到的各類方案,不乏黑科技,然而存在的問題仍是一大堆,若是團隊的開發者執行力不夠,中途容易出現各類麻煩。因此真正可以解決這個問題的,必然仍是瀏覽器自己!我要說話
爲何不能給用戶提供這樣一個 API,即便頁面跳轉了,也可以將上個頁面的請求發出去呢?慶幸的是,W3C 工做組也想到了這個問題,提出了 Beacon API
的 草案。我要說話
Beacon API
容許開發者發送少許錯誤分析和上報的信息,它的特色很明顯:我要說話
sendBeacon
函數掛在在 navigator 上,在 unload 以前,這個函數必定是被初始化了的。其使用方式爲:我要說話
window.addEventListener('unload', function(event) { |
navigator.sendBeacon(url, data);
,第一個參數爲數據上報的地址,第二個參數爲要發送的數據,支持的數據格式有:ArrayBufferView, Blob, DOMString, 和 FormData。我要說話
Beacon
的還有一個很是實用的移動端使用場景,當用戶從瀏覽器切換到其餘 app 界面或者 Home 屏的時候,部分瀏覽器默認會中止頁面腳本的執行,若是在這個時候使用了 unload 時間,可能會讓你失望,由於 unload 事件並不會觸發,此時,Beacon
就派上用途了,它是不會受影響的。我要說話
本文是對頁面打點丟失問題的簡單探討,枚舉了咱們一般會用到的一些解決方案,可能不是很完善,若是你有更好的建議,能夠提出來。我要說話
不少問題,咱們絞盡腦汁,可能不多會考慮,這個問題是否是應該有咱們來解決,或者說這個問題交給誰處理是最恰當的。本文的探討能夠看到,瀏覽器自己纔是最好的問題解決方,當網站流量變大以後,上面提到的丟失問題就更加明顯,這也迫使瀏覽器自己作了改善,天然也在情理之中。