記錄--前端性能監控初步實戰

来源:https://www.cnblogs.com/smileZAZ/archive/2023/01/11/17044397.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 在當下前後端分離的主流環境下,前端部分的優化變得越來越重要。為了提升前端的性能和用戶體驗,我覺得可能需要從三個維度採集數據進行分析。 前端埋點。通過埋點收集和統計網頁的UV/PV、設備型號、瀏覽器等數據進行分析,比如可以有針對性對使 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

前言

在當下前後端分離的主流環境下,前端部分的優化變得越來越重要。為了提升前端的性能和用戶體驗,我覺得可能需要從三個維度採集數據進行分析。

  1. 前端埋點。通過埋點收集和統計網頁的UV/PV、設備型號、瀏覽器等數據進行分析,比如可以有針對性對使用比較靠前的設備、瀏覽器等做優化和體驗。
  2. 網頁性能收集和監控。 採集一個頁面從請求開始到完成這個過程中的數據指標。比如收集和監控首屏載入時間、dom渲染時長、響應比較慢的介面等。有了這些數據可以很直觀和針對性的對網頁的性能進行優化和升級。
  3. 錯誤收集和監控。收集網頁中的js的報錯、靜態資源載入報錯,保證網頁正常訪問和降低bug率。

1.前端埋點

採集用戶的行為,監控產品在用戶端的使用情況,根據數據可以明確,前端可以針對性的做優化和體驗。

可以簡單的初步建立這樣的數據模型:

{
 ip: ip地址,統計uv
 ua: 瀏覽器的userAgent //方便區分瀏覽器的品牌
 os: 系統名稱
 current_page_all: 當前頁面訪問總次數
 width:瀏覽器寬度,   
 height:瀏覽器高度, //統計瀏覽器的尺寸
 current_enter_time: 進入當前頁面的時間戳
 current_leave_time: 離開當前頁面的時間戳
 project_id: 項目的id,
 url: 當前url,
 user_uni_id: 臨時分配給用戶唯一的id
 ....
 還有其他
}

2.在網頁中植入對應的js代碼

//進入
document.addEventListener('DOMContentLoaded',function(){
   ...
   let args = {
     ua: navigator.userAgent,
     os: navigator.platform,
     width: document.body.clientWidth || document.documentElement.clientWidth,
     height: document.body.clientHeight || document.documentElement.clientHeight,
     project_id: md5('abcd'),
     user_uni_id: '臨時分配給用戶唯一的id',
     url: window.location.href,
     current_enter_time: new Date().getTime()
     ....
   };
   let img = new Image();
   img.onload = function() {
     img = null;
   };
   img.src= `https://localhost:9700/bury.gif?args=${qs(args)}`;
 });

//離開
window.onbeforeunload = function() {
   ...
   let args = {
     ...
     leave_time: new Date().getTime()
     ....
   };
   let img = new Image();
   img.onload = function() {
     img = null;
   };
   img.src= `https://localhost:9700/bury.gif?args=${qs(args)}`;
}
  1. 收集數據並上報
const fs = require('fs');
route.get('/bury.gif',async (ctx)=>{
  let queryStr = ctx.querystring;
  let d = new Date();
  let year = d.getFullYear();
  let month = d.getMonth()+1;
  let day = d.getDate()+1;
  fs.writeFile(`../logs/${year}-${month}-${day}.log`,queryStr,{flag:'a',encoding:'utf-8',mode:'0666'},function(e){});
   ctx.status = 200;
   ctx.type = 'image/gif';
   ctx.body = {};
});

簡單的設想方案是先把數據收集到文本文件里,然後定時的分析這些文本文件,然後把篩選後的放到資料庫中。

2.網頁性能收集

網頁性能主要是收集是輸入url地址到網頁請求完成資源下載完成這段時間範圍內一些請求、載入等指標。

  • 比如舉幾個簡單的指標:

  • 首屏載入時長

  • HTML 文檔被載入和解析完成

  • 網頁載入完成時間

  • 白屏時間

  • 其他…

  1. 具體實現方案(一):
//index.html
<html>
 <head>
   <script>
     window.startTime = Date.now();
   </script>
 </head>
 <body>
   <script>
     let diff = Date.now()-window.startTime;
     console.log('白屏時長'+diff);
     document.addEventListener('DOMContentLoaded',()=>{
       console.log('HTML 文檔被載入和解析完成時間'+Date.now()-window.startTime); 
     });
     window.onload = function() {
       console.log('網頁載入完成時間'+Date.now()-window.startTime); 
     };
   </script>
   <script src="a.js"></script>
   <script src="b.js"></script>
   ....
 </body>
</html>

使用performance API

Performance是W3C性能小組引入進來的一個新的API,他可以很好的獲取到首屏載入時間、白屏時間、dns查詢時間等,是一個很方便的獲取網頁性能指標的API,而且目前大部分主流瀏覽器是支持的。

https://www.caniuse.com/

1.Performance一些常用用法的總結

let timing = window.performance.timing
//白屏時間
timing.responseStart - timing.navigationStart
//DNS 查詢時長
timing.domainLookupEnd - timing.domainLookupStart
//request請求耗時
timing.responseEnd - timing.responseStart
//HTML 文檔被載入和解析完成耗時
timing.domComplete - timing.domInteractive
//網頁載入完成耗時
timing.loadEventEnd - timing.navigationStart
//重定向耗時
timing.redirectEnd - timing.redirectStart;
//占用的記憶體
window.performance.memory.usedJSHeapSize;

2.此外還有一些高級用法,比如可以收集一些請求和靜態資源的請求時間

let  time = [];
let entryLists = window.performance.getEntries();
for(let i=0;i<entryLists.length;i++) {
  let item = entryLists[i];
  let obj = {};
     let soureTypes = ['script','css','xmlhttprequest','link','img'];
     if(soureTypes.indexOf(item.initiatorType)>=0){
       obj.name = item.name;  
       //請求時間
       obj.reqTime = item.responseEnd - item.responseStart;
       time.push(obj);
     }
}

3.關於Performance的更多用法可以參考:

https://www.jianshu.com/p/1355232d525a
https://blog.csdn.net/hb_zhouyj/article/details/89888646

4.收集數據上報

收集上報數據,使用koa2創建介面performance.gif

const fs = require('fs');
route.get('/performance.gif',async (ctx)=>{
  let queryStr = ctx.querystring;
  let d = new Date();
  let year = d.getFullYear();
  let month = d.getMonth()+1;
  let day = d.getDate()+1;
  fs.writeFile(`../performance-logs/${year}-${month}-${day}.log`,queryStr,{flag:'a',encoding:'utf-8',mode:'0666'},function(e){});
   ctx.status = 200;
   ctx.type = 'image/gif';
   ctx.body = {};
});

3.錯誤收集和監控

錯誤收集主要就是針對js報錯、靜態資源載入等出錯信息進行收集。

  1. 收集js報錯最先想到的可能是try catch。
try {
    console.log(b);
    } catch(e) {
      console.log(e);
      sendErrorReq();
    };

但是使用使用的話,每個頁面收集錯誤都要充斥這try catch,這樣其實是不太好的。

而且catch似乎沒辦法捕獲到非同步的操作。

try {
      setTimeout(()=>{
       console.log(b); 
      })
    } catch(e) {
      console.log(e);
      sendErrorReq();
    };

試了一下沒有執行到catch裡邊的sendErrorReq函數。

使用try catch是一種局部錯誤監聽方式。

  1. 用window.onerror或者是window.addEventListener(‘error’)

window.onerror

/**
      *msg 錯誤信息
      *url 錯誤所在的頁面地址
      *row 錯誤所在的行數
      *col 錯誤所在的列數
      **/
     window.onerror = function(msg,url,row,col) {
       console.log(msg,url,row,col, error);
     };
    b();

使用window.onerror可以檢測到js的報錯,但是沒法監聽靜態資源載入失敗的情況。

<img src="一個不存在的圖片地址" alt="">

window.addEventListener(‘error’)

window.addEventListener(‘error’)能夠監聽到靜態資源載入出錯

window.addEventListener('error',(e)=>{
      let localName = e.srcElement.localName;
      let currentSrc = e.srcElement.currentSrc;
      if(localName=='img') {
        console.log(`圖片${currentSrc}載入失敗了`);
        sendErrorData(currentSrc);
      }
      ...
      // e.preventDefault();
    },true);

必須設為捕獲過程中執行,否則依然無法監聽。

3. promise錯誤的收集

new Promise((resolve,reject)=>{
       reject('hi');
    }).catch(e=>{
      console.log(e);
      sendErrorData(e)
    });
axios.get(...).catch(e=>{
  console.log(e);
   sendErrorData(e)
})

但是有種情況,如果promise不加catch的話,
沒法通過window.onerror去監聽,但是還是通過監聽unhandledrejection事件去收集的

4.unhandledrejection

window.addEventListener('unhandledrejection', event => {
       console.log('error:'+event.reason); 
        sendErrorData(event.reason);
    });   
    new Promise((resolve,reject)=>{
       reject('hi');
    });

在看下在vue中收集報錯,以vue-cli3創建的項目進行演示

測試了一下window.onerror這種方式 無法監聽錯誤的。

在網上找了下原因

可以看到在vue的源碼里,因為如果沒有定義errorHandler就會走到logError這個方法,所以沒法使用window.onerror進行監聽。

5.errorHandler

在vue的手冊中,推薦監聽vue報錯的可以使用errorHandler這個配置方法。

//main.js
Vue.config.errorHandler = function (err, vm, info) {
  console.log('錯誤是:', err)
  sendErrorData(err);
}
然後隨便故意寫錯
mounted() {
  a();
}
  就能收集到報錯信息了

 當然最後把收集的錯誤上報給伺服器,創建一個介面error.gif。

const fs = require('fs');
route.get('/error.gif',async (ctx)=>{
  let queryStr = ctx.querystring;
  ....
  fs.writeFile(`../error-logs/${year}-${month}-${day}.log`,queryStr,{flag:'a',encoding:'utf-8',mode:'0666'},function(e){});
   ctx.status = 200;
   ctx.type = 'image/gif';
   ...
});

本文轉載於:

http://events.jianshu.io/p/a6572eb10e00

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 隨著數據量的增大,傳統關係型資料庫越來越不能滿足對於海量數據存儲的需求。對於分散式關係型資料庫,我們瞭解其底層存儲結構是非常重要的。本文將介紹下分散式關係型資料庫 TiDB 所採用的底層存儲結構 LSM 樹的原理。 ...
  • 在使用MybatisPlus分頁功能時發現:前端查詢第一頁是沒問題的,但是向後查詢的時候數據始終是第一頁的 查詢第一頁的時候發現沒有任何問題 往後查詢,比如查詢第二頁時數據和第一頁一樣 開始以為是代碼問題,把sql單獨拿出來執行發現還是會有重覆數據 上網查詢發現是因為ORDER BY排序的欄位有重覆 ...
  • 分享概要 一、業務場景 二、架構演進 三、架構設計 四、穩定性 五、效率 一、業務場景 在開始講解之前,我先為大家介紹一下B站的業務場景。B站的業務大體上可以分為以下幾類: 1、點播類業務 點播類業務就是大家經常看的視頻以及稿件之類相關的業務,這類數據使用場景的特點有: 數據一致性要求較高 耗時敏感 ...
  • 前言 最近閱讀 Catcher、BugSnag、Rollbar 三個 Flutter 異常監控開源框架,文章鏈接如下: Flutter 異常監控 - 壹 | 從 Zone 說起 Flutter 異常監控 - 貳 | 框架 Catcher 原理分析 Flutter 異常監控 - 叄 | 從 bugsn ...
  • 一、推送成功收不到消息,推送返回:{"message":"success","requestID":"1523868*****2842718","resultcode":0} 排查步驟: 1、網路不穩定,切換穩定網路進行測試; 2、檢查手機是否為EMUI8.0.0系統,如果是早期的EMUI8.0,則 ...
  • Vue.js是一個漸進式的JavaScript框架,它使用了響應式系統來維護應用程式的狀態。響應式系統是Vue.js的核心部分,它使得應用程式能夠自動地更新視圖,當數據發生變化時。 ...
  • Vue04 12.Vue2 腳手架模塊化開發 目前開發模式的問題: 開發效率低 不夠規範 維護和升級,可讀性比較差 12.1基本介紹 官網地址 什麼是Vue Cli腳手架 12.2環境配置,搭建項目 VUE安裝教程+VScode配置 搭建Vue腳手架工程,需要用到NPM(node package m ...
  • Flexbox 是 CSS3 中的一種佈局模式。它允許元素在一個容器中自動排列,可以使用靈活的方式創建複雜的佈局。Flex 佈局有很多優點,例如,它很容易實現響應式設計,並且可以很容易地對齊和排列元素。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...