摘要: 網頁應該如何錄屏呢?
Fundebug經授權轉載,版權歸原作者所有。
關鍵點
- 首先,每一次會話都有一個唯一的session ID,這是串聯起所有行為的紐帶。
- 其次,用戶行為又分成兩個部分,其一是用戶的操作,比如鼠標滑動,點擊,頁面滾動等,其二是頁面的變化。這兩者我們都統稱為用戶行為,記錄在同一個隊列中。
- 一開始的時候,系統會記錄下初始的頁面作為第一幀,這是唯一的一次完整頁面記錄。
- 針對用戶操作,我們會記錄事件的類型,鼠標位置等關鍵信息,保存到隊列中。
- 針對頁面變動,我們會起一個mutationObserve偵聽頁面的改動,每次只記錄改動的部分,保存到隊列中。
- 無論是事件還是頁面改動,都是對等的一幀,每一幀都會有當前時間,與上一幀間隔時間等基本信息用戶還原
- 一旦出錯,SDK就把隊列發送到監控系統,並清空當前隊列。
- 還原端根據記錄的行為隊列,根據時間逐一播放出來。最終形成一個類似於視頻的效果。
初步思路
方式一:
- 前端收集信息,首先,初始化的時候記錄一個頁面的初始狀態,然后利用 MutationObserver 監聽dom的改變事件,然后監聽所有的鼠標事件、滾動事件等等所有的頁面變化。
- 在合理的時機把這些信息隊列上傳到服務器,如頁面出錯時等。
- 后台分析前端收集到的信息,轉為圖片,然后形成"視頻",或者用戶行為棧。提供對應的調用 api。
- 前端需要查找問題時,根據用戶id等信息找到對應的出錯棧。
方式二:
- 前端根據 html 轉為對應的圖片(可以轉為 base64 格式)
- 將圖片發送給后台
- 后台將圖片按序組成"視頻"
現有SDK
錄屏(截圖)
- html2canvas
- puppeteer
- rrweb+rrweb-player+rrweb-snapshot
html2canvas介紹
html2canvas 是通過分析頁面中已加載好的 DOM 元素,然后 canvas 將生成的 DOM 節點繪制在畫布上,最后轉換為圖片。它不是真正的截屏,只是根據頁面元素信息還原出圖片,所以並不是 100% 和頁面相同的。
局限性
- 頁面中的圖片不能跨域
- 不是所有的 css 特性都支持,如不支持 box-shadow、filter 等
- 不支持截取插件內容,如 Flash
- 不支持 iframe 內容
瀏覽器支持
- Firefox 3.5+
- Google Chrome
- Opera 12+
- IE9+
- Edge
- Safari 6+
puppeteer介紹
Puppeteer 是 Google Chrome 團隊官方的無界面(Headless)Chrome 工具,它是一個 Node 庫,提供了一個高級的 API 來控制 DevTools協議上的無頭版 Chrome 。
局限性
- Puppeteer 需要 Chromium。其主要應用在自動化測試上。
功能
- 生成頁面的截圖和PDF。
- 抓取SPA並生成預先呈現的內容(即"SSR")。
- 從網站抓取你需要的內容。
- 自動表單提交,UI測試,鍵盤輸入等
- 創建一個最新的自動化測試環境。使用最新的JavaScript和瀏覽器功能,直接在最新版本的Chrome中運行測試。
- 捕獲您的網站的時間線跟蹤,以幫助診斷性能問題。
結論html2canvas 更適合於 C 端的用戶行為截圖跟蹤,而 Puppeteer 適用於自動化測試。
rrweb介紹
rrweb 主要由 3 部分組成:
- rrweb-snapshot,包含 snapshot 和 rebuild 兩個功能。snapshot 用於將 DOM 及其狀態轉化為可序列化的數據結構並添加唯一標識;rebuild 則是將 snapshot 記錄的數據結構重建為對應的 DOM。
- rrweb,包含 record 和 replay 兩個功能。record 用於記錄 DOM 中的所有變更(mutation);replay 則是將記錄的變更按照對應的時間一一重放。
- rrweb-player,為 rrweb 提供一套 UI 控件,提供基於 GUI 的暫停、快進、拖拽至任意時間點播放等功能。
rrweb適用場景:
- 用戶行為分析;
- 遠程debug;
- 錄制操作;
- 實時協作;
局限性
- 社區資源較少
- 部分代碼用較舊的模式寫的,有未知坑
最終結論
綜合來看,結合思路一,基於 rrweb 來開發是最可行最快捷的。
Demo
目前,我基於 rrweb 已經做了個 demo 出來。以下是初步成果:demo代碼
補充資料
rrweb的一些思路原理
MutationObserver介紹
Mutation Observer API 用來監視 DOM 變動。DOM 的任何變動,比如節點的增減、屬性的變動、文本內容的變動,這個 API 都可以得到通知。
特點
- 它等待所有腳本任務完成后,才會運行(即異步觸發方式)。
- 它把 DOM 變動記錄封裝成一個數組進行處理,而不是一條條個別處理 DOM 變動。
- 它既可以觀察 DOM 的所有類型變動,也可以指定只觀察某一類變動。
example
Select the node that will be observed for mutations var targetNode = document.getElementById('some-id');
// Options for the observer (which mutations to observe)
var config = { attributes: true, childList: true, subtree: true };
// Callback function to execute when mutations are observed
var callback = function(mutationsList, observer) {
for (var mutation of mutationsList) {
if (mutation.type == "childList") {
console.log("A child node has been added or removed.");
} else if (mutation.type == "attributes") {
console.log(
"The " + mutation.attributeName + " attribute was modified."
);
}
}
};
// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode, config);
// Later, you can stop observing
observer.disconnect();
observe方法接受兩個參數,第一個是所要觀察的DOM元素是article,第二個是所要觀察的變動類型(子節點變動和屬性變動),方法調用時必須指定一種或多種變動類型,否則報錯,變動類型如下:
boolean childList = false;
boolean attributes;
boolean characterData;
boolean subtree = false; //表示是否將該觀察器應用於該節點的所有后代節點。
boolean attributeOldValue; //表示觀察attributes變動時,是否需要記錄變動前的屬性值。
boolean characterDataOldValue; //表示觀察characterData變動時,是否需要記錄變動前的值。
sequence<DOMString> attributeFilter;//數組,表示需要觀察的特定屬性(比如['class','src'])
disconnect方法用來停止觀察。調用該方法后,DOM 再發生變動,也不會觸發觀察器。 takeRecords方法用來清除變動記錄,即不再處理未處理的變動。該方法返回變動記錄的數組。
MutationRecord對象
DOM 每次發生變化,就會生成一條變動記錄(MutationRecord 實例)。該實例包含了與變動相關的所有信息。Mutation Observer 處理的就是一個個MutationRecord實例所組成的數組。 MutationRecord對象包含了DOM的相關信息,有如下屬性:
type:觀察的變動類型(attribute、characterData或者childList)。
target:發生變動的DOM節點。
addedNodes:新增的DOM節點。
removedNodes:刪除的DOM節點。
previousSibling:前一個同級節點,如果沒有則返回null。
nextSibling:下一個同級節點,如果沒有則返回null。
attributeName:發生變動的屬性。如果設置了attributeFilter,則只返回預先指定的屬性。
oldValue:變動前的值。這個屬性只對attribute和characterData變動有效,如果發生childList變動,則返回null。
關於Fundebug
Fundebug專注於JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java線上應用實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了20億+錯誤事件,付費客戶有陽光保險、核桃編程、荔枝FM、掌門1對1、微脈、青團社等眾多品牌企業。歡迎大家免費試用!