摘要:前言最近有幸參與一個前端質量監控類項目的重構,算是個人初次接觸到前端質量監控相關的知識,對于其中的性能統計部分很感興趣,查詢資料之后寫了文章,作為個人學習記錄,如有錯誤,敬請斧正頁面整體性能通過瀏覽器提供的方法,我們能夠得到網頁每個處理階段
前言
最近有幸參與一個前端質量監控類項目的重構,算是個人初次接觸到前端質量監控相關的知識,對于其中的性能統計部分很感興趣,查詢資料之后寫了文章,作為個人學習記錄,如有錯誤,敬請斧正
1.頁面整體性能通過瀏覽器提供的 window.performance.timing 方法,我們能夠得到網頁每個處理階段的精確時間。打開一個頁面后,這些信息會被瀏覽器記錄下來,我們直接在控制臺輸出,就可以查看結果
該對象下有多個字段,每個字段都對應著瀏覽器加載一個頁面的某個階段,下面這張圖詳細的展示了瀏覽器加載一個頁面的詳細過程
https://segmentfault.com/img/...
window.performance = { timing: { // 同一個域下,前一個網 unload 的時間戳, // 如果直接復制地址進入或者不是同域 // 則與 fetchStart 值相等 navigationStart: 1441112691935, // 前一個網頁unload 的時間戳, // 如果無前一個網頁 unload // 或者前一個網頁與當前頁面不同域,則值為 0 unloadEventStart: 0, // 和 unloadEventStart 相對應 // 返回前一個網頁 unload 事件綁定的回調函數執行完畢的時間戳 unloadEventEnd: 0, // 第一個 HTTP 重定向發生時的時間。 // 有跳轉且是同域名內的重定向才算 // 否則值為 0 redirectStart: 0, // 最后一個 HTTP 重定向完成時的時間 // 有跳轉且是同域名內部的重定向才算 // 否則值為 0 redirectEnd: 0, // 瀏覽器準備好使用 HTTP 請求抓取文檔的時間 // 發生在檢查本地緩存之前 fetchStart: 1441112692155, // DNS 域名查詢開始的時間 // 如果使用了本地緩存(即無 DNS 查詢)或持久連接 // 則與 fetchStart 值相等 domainLookupStart: 1441112692155, // DNS 域名查詢完成的時間 // 如果使用了本地緩存(即無 DNS 查詢)或持久連接 // 則與 fetchStart 值相等 domainLookupEnd: 1441112692155, // HTTP(TCP) 開始建立連接的時間 // 如果是持久連接,則與 fetchStart 值相等 // 注意如果在傳輸層發生了錯誤且重新建立連接, // 則顯示的是新建立的連接開始的時間 connectStart: 1441112692155, // HTTP(TCP) 完成建立連接的時間(完成握手) // 如果是持久連接,則與 fetchStart 值相等 // 注意如果在傳輸層發生了錯誤且重新建立連接, // 則顯示的是新建立的連接完成的時間 // 注意這里握手結束,包括安全連接建立完成、SOCKS 授權通過 connectEnd: 1441112692155, // HTTPS 連接開始的時間, // 如果不是安全連接,則值為 0 secureConnectionStart: 0, // HTTP 請求讀取真實文檔開始的時間(完成建立連接 // 包括從本地讀取緩存 // 連接錯誤重連時,這里顯示的也是新建立連接的時間 requestStart: 1441112692158, // HTTP 開始接收響應的時間(獲取到第一個字節) // 包括從本地讀取緩存 responseStart: 1441112692686, // HTTP 響應全部接收完成的時間(獲取到最后一個字節) // 包括從本地讀取緩存 responseEnd: 1441112692687, // 開始解析渲染 DOM 樹的時間 // 此時 Document.readyState 變為 loading // 并將拋出 readystatechange 相關事件 domLoading: 1441112692690, // 完成解析 DOM 樹的時間 // Document.readyState 變為 interactive // 并將拋出 readystatechange 相關事件 // 注意只是 DOM 樹解析完成 // 此時并沒有開始加載網頁內的資源 domInteractive: 1441112693093, // DOM 解析完成后,網頁內資源加載開始的時間 // 在 DOMContentLoaded 事件拋出前發生 domContentLoadedEventStart: 1441112693093, // DOM 解析完成后, // 網頁內資源加載完成的時間 // 如 JS 腳本加載執行完 domContentLoadedEventEnd: 1441112693101, // DOM 樹解析完成 // 且資源也準備就緒的時間 // Document.readyState 變為 complete // 此時拋出 readystatechange 相關事件 domComplete: 1441112693214, // load 事件發送給文檔 // 也即 load 回調函數開始執行的時間 // 注意如果沒有綁定 load 事件,值為 0 loadEventStart: 1441112693214, // load 事件的回調函數執行完畢的時間 loadEventEnd: 1441112693215 } }
通過這些值,我們就能得到某個階段具體的時間差,進行一些簡單的計算, 就能夠得到網頁的各項性能數據,便于我們在某個階段做優化
// DOM解析時間 var domParseTime = domComplete - responseEnd; // DNS解析時間 var domainLookUpTime = domainLookupEnd - domainLookupStart;2. 頁面中各個資源的性能
上面我們用 window.performance.timing 方法得到的是整個頁面的耗時,在一些情況下,我們想要知道頁面上某個靜態資源的加載時間,那么我們就可以用三個方法來獲取這些信息
window.performance.getEntries // 返回網頁中所有資源和標記的數據
window.performance.getEntriesByType // 根據entryType返回數據
window.performance.getEntriesByName // 根據name返回數據
其中 window.performance.getEntries 可以獲取到所有資源信息和所有標記信息(何為標記信息,我們后面會講到), 而我們想看的只是 entryType: "resource" 這些資源的信息,所以我們可以直接使用 window.performance.getEntriesByType("resource") 方法來獲得我們的信息,該方法會返回一個數組,包含字段如下
var entries = [{ // 資源的絕對路徑 name: "http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js", // 資源類型 entryType: "resource", // css: 通過css請求的資源。類型不定 // img: 圖片 // link: 通過link標簽請求的資源: css/favicon // script: js文件 // xmlhttprequest: 一般為GET方式的數據接口 initiatorType: "script", // 加載時間 duration: 18.13399999809917, // 這些字段的意義同上面 // 不同之處只表示這一個資源的時間 redirectStart: 0, redirectEnd: 0, fetchStart: 233.346999992829828, domainLookupStart: 0, domainLookupEnd: 0, connectStart: 0, connectEnd: 0, secureConnectionStart: 0, requestStart: 0, responseStart: 0, responseEnd: 442.7109999960521, startTime: 424.57699999795295 }];
這些數據里面,initiatorType的值需要注意下, initiatorType 并不是指資源的類型,而是指 請求該資源的請求類型, 如上圖所示 initiatorType: "css" 的時候,資源文件并不是一個css文件,而是一張 img圖片,表明該圖片是通過css去請求到的(通常是設置背景圖),而直接在網頁中通過 或在代碼中通過 new Image 請求的圖片,initiatorType 值都為 img,我們以下面這段代碼為例
通過CSS加載的圖片
通過 img 標簽直接加載
通過 new Image() 加載的圖片
打開頁面之后在控制臺輸出結果, 也驗證了結果
另外值得注意的一個點是,除了這三張圖片,我們在頁面中還加載了2個css文件和1個js文件,分別是
index.css // 本地文件
bootstrap.min.css // 遠程
jquery.min.js // 遠程
仔細觀察的話,會發現這幾個文件有一些不同之處,我們對數據稍作處理,方便參看
我們會發現,其中的 bootstrap.min.css 的很多字段數據都為0,查詢資料之后才知道,該方法通常情況下只能獲得本域名下資源的加載信息(所以 index.css 的信息直接就能獲取到)
如果想要獲取遠程資源的加載信息的只有在response里面顯式的設置 Timing-Allow-Origin:* 類似于(Acces-Control-Allow-Origin的設置)
我們直接打開了 jquery.min.js 連接, 看到了 Timing-Allow-Origin 字段,所以我們能夠獲得該資源的準確信息, 而在 bootstrap.min.css 的返回中,我們沒有找到 Timing-Allow-Origin 字段, 所以數據都顯示為0
3. 代碼執行計時通常情況下,我們想要取得一段代碼的執行時間,會做以下操作
var start = +new Date(); for (var i = 0; i < 100; i++) { ret.push(i); } var end = +new Date(); console.log("執行時間", end - start);
但不足之處在于, new Date 的精確度只到秒, 而有時候我們的代碼執行在1s之內,計算出的差值為0,此時就顯得無能為力。所以,我們可能通過如下兩種方式,解決這個問題
1. 通過 window.performance.nowvar start = window.performance.now(); for (var i = 0; i < 100; i++) { ret.push(i); } var end = window.performance.now(); console.log("執行時間", end - start);
使用方式十分簡單,該方法能夠計算出精確到 百萬分之一秒 的時間差。與 new Date 不同之處在于 window.performance.now 方法返回的是相對于 performance.timing.navigationStart 即頁面初始化的時間,但我們的關注點是差值, 所以時間從哪兒算起,對于我們來說并不重要
2. 使用 window.performance.mark 和 window.performance.measure// 標記開始 window.performance.mark("start"); for (var i = 0; i < 100; i++) { ret.push(i); } // 標記結束 window.performance.mark("end"); // 計算差值并命名為difference, 無返回 window.performance.measure("difference", "start", "end");
通過 window.performance.mark 方法,我們在指定地方打上一個記號,此時不會返回任何值,會被記錄到performance 對象里, entryType 被默認標記為了 mark。
然后通過 window.performance.measure 計算出差值,并通過第一個參數對其賦名為 difference, 此時也沒有返回值,這些值也被記錄到了 performance 對象里,它們的 entryType 被默認標記為了 measure.
所以我們可以通過兩種方式來查看差值
window.performance.getEntriesByType("measure")
`window.perform
esByName("difference")`
![圖片上傳中...]
在使用完了之后,我們還可以對這些標識,進行統一的清理
// 清除指定標記點 window.performance.clearMarks("start"); // 清除所有標記點 window.performance.clearMarks(); // 清除指定差值數據 window.performance.clearMeasures("difference"); // 清除所有差值數據 window.performance.clearMeasures();
通過這兩種方式,都可以精確的計算出十分精確的時間差值,那如何做選擇呢? 我的建議是,如果只是單純的想要得到少數的差值,直接在代碼中使用 now, 而如果需要統計大量的值, 就應該使用 mark 和 measure 方法,因為這些值都會存在 performance 對象里,我們可以在任意需要的時候,通過讀取數組,十分便捷的對數據做統一處理與管理
API支持 && 參考瀏覽器對Performance支持情況
http://www.infoq.com/cn/articles/html5-performance-api-monitoring
http://ju.outofmemory.cn/entry/204774
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99107.html
摘要:基本入門前端掘金作者本文屬于翻譯文章,原文鏈接為。如果如何把應用放在容器中運行掘金本文適合零基礎,且希望使用運行應用的人士。后端掘金使用構建網站。 nginx 基本入門 - 前端 - 掘金作者:villainthr 本文屬于翻譯文章,原文鏈接為 nginx Beginner’s Guide。是至今為止見過最好的 nginx 入門文章。額。。。沒有之一。 這篇教程簡單介紹了 nginx ...
摘要:前言月份開始出沒社區,現在差不多月了,按照工作的說法,就是差不多過了三個月的試用期,準備轉正了一般來說,差不多到了轉正的時候,會進行總結或者分享會議那么今天我就把看過的一些學習資源主要是博客,博文推薦分享給大家。 1.前言 6月份開始出沒社區,現在差不多9月了,按照工作的說法,就是差不多過了三個月的試用期,準備轉正了!一般來說,差不多到了轉正的時候,會進行總結或者分享會議!那么今天我就...
閱讀 923·2023-04-26 01:34
閱讀 3356·2023-04-25 20:58
閱讀 3262·2021-11-08 13:22
閱讀 2108·2019-08-30 14:17
閱讀 2522·2019-08-29 15:27
閱讀 2673·2019-08-29 12:45
閱讀 2996·2019-08-29 12:26
閱讀 2811·2019-08-28 17:51