1背景
我們知道,目前主流的前端監控(百度統計/友盟/谷歌統計)都在用GIF進行打點。但是,爲什麼這些系統都會使用GIF,難道是因爲沒有其他的解決方案嗎?
這得從前端監控的原理說起。
2前端監控的原理
所謂的前端監控,其實是在滿足一定條件後,由Web頁面將用戶信息(UA/鼠標點擊位置/頁面報錯/停留時長/etc)上報給服務器的過程。一般是將上報數據用url_encode(百度統計/CNZZ)或JSON編碼(神策/諸葛io)爲字符串,通過url參數傳遞給服務器,然後在服務器端統一處理。
這套流程的關鍵在於:
1)能夠收集到用戶信息;
2)能夠將收集到的數據上報給服務器。也就是說,只要能上報數據,無論是請求GIF文件還是請求js文件或者是調用頁面接口,服務器端其實並不關心具體的上報方式。
向服務器端上報數據,可以通過請求接口,請求普通文件,或者請求圖片資源的方式進行。爲什麼所有系統都統一使用了請求GIF圖片的方式上報數據呢?
3爲什麼主流方案用GIF上報數據
解答這個問題,要用排除法。
首先,爲什麼不能直接用GET/POST/HEAD請求接口進行上報?
這個比較容易想到原因。一般而言,打點域名都不是當前域名,所以所有的接口請求都會構成跨域。而跨域請求很容易出現由於配置不當被瀏覽器攔截並報錯,這是不能接受的。所以,直接排除。
可能的方式_排除接口請求
其次,爲什麼不能用請求其他的文件資源(js/css/ttf)的方式進行上報?
這和瀏覽器的特性有關。通常,創建資源節點後只有將對象注入到瀏覽器DOM樹後,瀏覽器纔會實際發送資源請求。反覆操作DOM不僅會引發性能問題,而且載入js/css資源還會阻塞頁面渲染,影響用戶體驗。
但是圖片請求例外。構造圖片打點不僅不用插入DOM,只要在js中new出Image對象就能發起請求,而且還沒有阻塞問題,在沒有js的瀏覽器環境中也能通過img標籤正常打點,這是其他類型的資源請求所做不到的。
所以,在所有通過請求文件資源進行打點的方案中,使用圖片是最好的解決方案。
可能的方式_排除文件請求
那還剩下最後一個問題,同樣都是圖片,上報時選用了1x1的透明GIF,而不是其他的PNG/JEPG/BMP文件。
這是排除法的最後一步,原因其實不太好想,需要分開來看。
首先,1x1像素是最小的合法圖片。而且,因爲是通過圖片打點,所以圖片最好是透明的,這樣一來不會影響頁面本身展示效果,二者表示圖片透明只要使用一個二進制位標記圖片是透明色即可,不用存儲色彩空間數據,可以節約體積。因爲需要透明色,所以可以直接排除JEPG(BMP32格式可以支持透明色)。
然後還剩下BMP、PNG和GIF,但是爲什麼會選GIF呢?
因爲體積!
下方是1x1像素透明圖,最小的BMP/PNG/GIF文件結構。
BMP:
BMP
PNG:
PNG
GIF:
GIF
可以看到,最小的BMP文件需要74個字節,PNG需要67個字節,而合法的GIF,只需要43個字節。
同樣的響應,GIF可以比BMP節約41%的流量,比PNG節約35%的流量。這樣比較一下,答案就很明顯了。
上報數據,顯然GIF纔是最佳選擇。
可能的選擇_最終結果
4總結
前端監控使用GIF進行上報主要是因爲:
-
沒有跨域問題;
-
不會阻塞頁面加載,影響用戶體驗;
-
在所有圖片中體積最小,相較BMP/PNG,可以節約41%/35%的網絡資源。