怎樣定位前端線上問題,一直以來,都是很頭疼的問題,由於它發生於用戶的一系列操做以後。錯誤的緣由可能源於機型,網絡環境,接口請求,複雜的操做行爲等等,在咱們想要去解決的時候很難復現出來,天然也就沒法解決。 固然,這些問題並不是不能克服,讓咱們來一塊兒看看如何去監控並定位線上的問題吧。 html
這是搭建前端監控系統的第六章,主要是介紹如何使用js進行頁面截圖,跟着我一步步作,你也能搭建出一個屬於本身的前端監控系統。前端
開源項目 : 前端監控系統
程序員
用戶對前端程序員來講,就是一個黑匣子。 若是用戶上報了一個錯誤,前端程序員就是兩眼一抹黑,由於不少錯誤是無法復現的。我問過不少前端工程師,他們的回答都是,若是你無法復現Bug,我怎麼去解決這個Bug呢。 那麼有沒有一個辦法能夠解決用戶和前端程序員之間的障礙呢, 讓用戶對咱們來講,再也不是黑匣子,而是透明化。用戶的頁面長什麼樣,他們都作了什麼操做,發生了什麼錯誤,咱們都可以清晰的知道,那麼,再有問題上報的時候,我就會頗有信心的說一句: I Can Fix it !web
最近試用了一下Fundebug,進入首頁,第一條即是 黑科技!支持錄屏。 這下就驚呆我了,js作前端監控,竟然還能錄屏? 你丫這是要逆天啊? 因此,趕忙註冊了帳號,進行試用。 chrome
通過各類配置後,進行測試發佈,發現毫無效果,因此詢問客服。 回答是: 目前錄製功能有bug,因此默認爲關閉狀態,將配置屬性silentVideo設置爲false便可。canvas
果不其然,通過客服的細心指導,終於成功了。 圖一爲電腦版chrome瀏覽器,能夠正常進行屏幕錄製。 圖二爲手機app自帶的webview瀏覽器,第一次點擊顯示灰屏,第二次點擊顯示爲電腦版的錄屏。通過測試,除了chrome以外,其餘瀏覽器均不支持。這讓我想起一個能夠進行js截屏的庫JSCapture, 也是隻支持chrome瀏覽器的。我猜測,Fundebug用的應該就是這個黑科技。 Fundebug也表示並不是真的視頻,應該是多作了幾幀截屏,而後順序切換,看着像視頻了。跨域
雖然是黑科技,可是也面臨着幾個比較大的問題:瀏覽器
1、由於支持的瀏覽器只有chrome,而chrome又是兼容性作得最好的瀏覽器了,不少問題在這個瀏覽器上根本不會發生, 因此這個黑科技仍是有待來日,也許會獲得更多瀏覽器的支持以後,才能真正的發揮做用。不得不感慨一句:唉,兼容性-前端程序員一輩子的宿命。服務器
2、就算屏幕錄製解決了,上傳了一個至少有個幾幀的仿視頻,這個流量大小但是很嚴重問題了,雖然Fundebug說是通過特殊處理壓縮後,一個視頻只有幾十KB,我總以爲不是很靠譜,感受比較難以實現(待驗證)微信
3、我本身的手機是iphone6 Plus, 當Fundebug在個人手機上進行屏幕捕捉的時候,手機都會卡頓好久。 我以前曾嘗試在iphone6上用js進行截圖,可是也會出現卡頓現象,這一點在微信瀏覽器上表現極爲明顯,甚至會致使微信從新刷新頁面。 好在iphone6以上的版本,截屏的效率都很高,不會再出現卡頓了
因此,Fundebug的黑科技是不可以普及的,可是咱們能夠換個思路來記錄用戶的行爲。
以前,我曾經考慮過一個需求,記錄下用戶的每一個行爲,訪問頁面的截圖,點擊按鈕的局部截圖,這樣,在錯誤發生的時候,就能清清楚楚的知道用戶在頁面上作了什麼,可是因爲截圖上傳須要耗費的流量確實太大,因此這個想法不得不放棄了。 今天,我看了Fundebug的黑科技,卻給了一些啓發。 我將針對以上提出的三個難點,完善頁面上用戶行爲追蹤功能。
用戶行爲追蹤功能
1、 上傳截圖,流量消耗過大怎麼辦,對圖片資源進行極致壓縮。
進行截圖後,須要上傳的數據很大,由於是圖片數據,多則大幾百Kb, 少則也有個上百Kb, 這麼大的流量,對用戶端,損耗確實過大。
首先,對js截圖進行了幾種測試,如圖:
以上截圖方式的參數以下:
參數 截圖方式一 截圖方式二 截圖方式三
壓縮前/後長度 28764/10787 93076/34903 168312/63118
圖片壓縮率 72% 40% 0%
截圖大小 21Kb 68.2Kb 123Kb
綜上分析,截圖方式一, 壓縮率高,雖然截圖不是很清晰,可是,也可以看得出,線上用戶頁面是什麼樣子的。
並且,也解決了,在低端機上截圖消耗性能過大的弊端,二十幾Kb的流量,也是咱們徹底可以接受的大小了。
因而可知,該方式可以徹底可以知足咱們追蹤用戶行爲的需求。
2、若是用戶量很是多, 用戶頻繁的上傳,也是一個大問題
因此,個人建議是分散流量,讓每一個用戶爲咱們貢獻至少一次頁面截圖:
① 每一個用戶都在隨機的頁面,隨機的時間上傳一個頁面截圖,以及一個點擊區域截圖,有且僅上傳一次,一個用戶的生命週期中只貢獻一次頁面截圖
② 每一個用戶發生某一類錯誤時,也只需上傳一個截圖便可,多個類型的錯誤,則上傳多個截圖。這樣能夠大量節省用戶的上傳次數。
③ 用戶的截圖數據很大, 時間長了須要很大的硬盤空間, 因此個人建議是,每一個流程頁面,只須要對應一個(點擊區域截圖,同理)。 每一個用戶的某一種類型的錯誤頁面也只對應一個(方便定位錯誤緣由)
如何截圖,如何壓縮上傳資源的大小
/** * js處理截圖 */ this.screenShot = function (cntElem, callback) { var shareContent = cntElem;//須要截圖的包裹的(原生的)DOM 對象 var width = shareContent.offsetWidth; //獲取dom 寬度 var height = shareContent.offsetHeight; //獲取dom 高度 var canvas = document.createElement("canvas"); //建立一個canvas節點 var scale = 0.6; //定義任意放大倍數 支持小數 canvas.style.display = "none"; canvas.width = width * scale; //定義canvas 寬度 * 縮放 canvas.height = height * scale; //定義canvas高度 *縮放 canvas.getContext("2d").scale(scale, scale); //獲取context,設置scale var opts = { scale: scale, // 添加的scale 參數 canvas: canvas, //自定義 canvas logging: false, //日誌開關,便於查看html2canvas的內部執行流程 width: width, //dom 原始寬度 height: height, useCORS: true // 【重要】開啓跨域配置 }; html2canvas(cntElem, opts).then(function(canvas) { var dataURL = canvas.toDataURL(); var tempCompress = dataURL.replace("data:image/png;base64,", ""); var compressedDataURL = Base64String.compress(tempCompress); callback(compressedDataURL); }); }
要作成這件事,必須依賴兩個js庫的幫忙了。
html2Canvas 執行html頁面截圖, lz-string 執行對字符串長度的壓縮,使用方式,如上方代碼所示。
因爲用戶行爲追蹤功能能夠由使用者選擇性開起, 因此,建議這兩個js庫文件有客戶端引入, 這樣就能夠減小探針代碼的大小, 如此,咱們就須要定義一個加載js文件的小工具
// 加載js文件的小工具
this.loadJs = function(url, callback) { var script = document.createElement('script'); script.async = 1; script.src = url; script.onload = callback; var dom = document.getElementsByTagName('script')[0]; dom.parentNode.insertBefore(script, dom); return dom; }
// html2Canvas 庫文件加載完成後,通知全局變量,lz-string 同理
utils.loadJs("//html2canvas.hertzen.com/dist/html2canvas.min.js",function () { html2CanvasLoaded = true; });
OK, 數據都已經準備穩當,剩下的就是要把這些數據存儲起來,並和用戶行爲,以及js錯誤關聯起來。 完成用戶行爲追蹤功能。
原本我覺得 前端Js錯誤監控模塊終結了, 可是發現還須要放上重要的一篇
下一章: 搭建前端監控系統(五)用戶行爲統計和監控