性能優化篇 - Performance(工具 & api)

前言

Performance 一個在前端開發領域中,沒法被忽視的存在,若是咱們的開發是一個知足需求就能夠的產品,那麼可能就用不到它;可是若是咱們想對咱們的這個產品,作一個極致的優化,那麼 Performance 是一個很好的選擇,也是一個不容忽視的選擇。javascript

Performance 工具 和 api 的優缺點

Performance 工具 優勢:

  • 可視化圖形界面
  • 每毫秒作的事情
  • 文件的執行加載的順序
  • 每毫秒界面展現的效果
  • 每一個方法執行的順序和時間(由下至上)
  • 倒置的事件火焰圖(由下至上)
  • 數據總結

Performance 工具 缺點:

  • 沒法查看某一個區間以內的運行時間
  • 沒法查看 js 堆的大小使用狀況及限制
  • 沒法查看頁面是刷新仍是加載,重定向次數
  • 沒法查看什麼時間開始作的性能測試
  • 能夠在資源緩存已滿的時候進行回調處理
  • 設置瀏覽器應在其性能條目緩衝區中保存的最大性能條目對象數

Performance api 優勢:

  • 徹底彌補了 Performance 工具 的缺點,還可讓咱們經過數據的方式去知道具體的時間

Performance api 缺點:

  • 沒法像 Performance 工具 那樣圖形化的去查看數據信息

大體的介紹了一下工具和api的優缺點,其實很明顯的能夠看出來,它們是相輔相成的,其實在通常的工具當中,咱們會使用其中的某一個去進行性能的優化,可是對於一個想要進行真正的,完全性的性能優化,仍是須要二者之間的配合,去進行更高效、更系統、更全面的優化。前端

Performance 工具

這就是 Performance 工具 的界面。vue

  • 上下箭頭,就是用來上傳和下載每一次性能檢測報告的;
  • no recordings 就是每一次的檢測報告,能夠根據每一次的檢測報告,去進行性能優化的對比;
  • Screenshots 是用來查看在每一個時間段界面的變化;
  • Memory 存儲調用棧的大小,在不一樣時間段的不一樣大小;

  • Disable Javascript samples 禁用 javascript 調用棧,在後面講解 Main 部分進行詳解;
  • Enable advanced paint instrumentation (slow) 記錄渲染事件的細節;
  • Network 用來修改檢測在不一樣的網絡環境下,界面的渲染;
  • CPU 用來查看電腦的性能問題;

到這裏呢,簡單的介紹了一下上面幾個按鈕真正的意義,下面結合可視化的圖表在配上面這些按鈕進行性能的檢測:java

這個性能檢測是對掘金網站 --> 個人主頁作的性能優化檢測截圖react

第一部分:概覽

這裏最主要是總體的界面渲染的時候,每一個時間段執行的事件順序,經過上圖,咱們就能知道咱們每一個時間段(精確到毫秒)都作了什麼,當鼠標放上去的時候,咱們還能夠大圖的形式去查看咱們每一個時間段界面的渲染狀況:api

當在這裏經過點擊滑動到某一位置鬆開的時候,能夠查看某一個區間直接的一個渲染狀況數組

第二部分:Network

Network 這裏咱們能夠看出來,咱們資源加載的一個順序狀況,什麼時間加載了什麼資源,經過這裏,咱們更直觀的能夠知道, 資源是並行加載的

第三部分:Frames

Frames 這裏,其實就是查看咱們在什麼時間,界面發生了改變,它和第一部分的區別就是在界面沒有改變的時候,它是不作記錄的,可是概覽部分是會作記錄的瀏覽器

第四部分: Interactions

在我看過的文章裏,不多看到會有這部分,是由於在不適用一些交互動做的時候,是不會有這部分的功能的,從這裏咱們看到了掘金使用了一些動畫的動做緩存

第五部分:Timings

這張圖不是掘金官網的,由於在項目打包後,就沒有對應的事件調用,因此在線上通過打包的網站,是看不到這部分的安全

第六部分:Main

這裏就是 Performance 工具 當中比較核心的一部分,俗稱 火焰圖 , 這裏是一個由下而上的事件執行圖,你能夠簡單的理解成上面這是一個彙總

第七部分:Raster

經過這裏,咱們知道掘金官網,在前端部分一共使用了幾條線程

這裏有一個知識點,這裏是指瀏覽器渲染的線程,而不是js的線程,特此聲明一下,怕被有的同窗拿js單線程來噴我😹
複製代碼

第八部分: GPU

這裏咱們能夠很清楚的看出來,網站在什麼時間有 GPU 加速

第九部分:taskSchedulerForegroundBlockingWorker

任務計劃程序前臺阻止工做程序,這裏我用的不多,也是第一次見,等的我明確一下這裏是作什麼的,在進行更新,若是有知道的朋友,也能夠評論告訴我,我及時進行改進

第十部分:Memory

上面有提到 Memory 選項,在勾選後,就會顯示該事件折線圖,經過該圖,能夠看出咱們在不一樣的時間段,不一樣事件的執行狀況

第十一部分:性能檢測詳情

上面有4個標籤:Summary(性能摘要)Bottom-Up(事件列表,由下至上,對應 Main 火焰圖)Call Tree(每一個事件的子項信息)Event log(事件日誌)

接下來,咱們依次詳解

Summary(性能摘要)

其實咱們一看就明白,它是一個用來統計在咱們檢測性能的時間範圍內,都作了哪些事情:

  • Loading :加載時間
  • Scripting :js計算時間
  • Rendering :渲染時間
  • Painting :繪製時間
  • Other :其餘時間
  • Idle :瀏覽器閒置時間

Bottom-Up(事件列表)

這裏和 Main 裏面看見的,實際上是一個對應着的關係,從這裏,咱們能夠看見全部的事件列表,還有每一個事件的 Self Time(本身調用的時間)Total Time(總調用時間,包括子項調用時間)Activity(行爲,包括調用該事件的位置)

Call Tree(事件子項信息)

其實這裏和 Bottom-Up 部分是同樣的,就不作太多的說明了,你們看一下就知道了

Event Log(事件日誌)

這裏比前面的 Bottom-UpCall Tree 相比,多了一個 Start Time 屬性,這個屬性其實就是開始的時間,從什麼時間開始執行的什麼事件

到這裏,有關 Performance 工具 的介紹,就到了這裏了,若是有什麼解釋不清楚的,或者有問題的地方,還請你們評論指出,我作及時的更正

下面,給你們介紹 Performance Api

Performance API

Performance 用來獲取當前頁面的性能信息,它和 Performance 工具 的區別在上面咱們已經寫出來了,就不在這裏囉嗦了

注意:除了如下指出的狀況外,該接口及其成員在 Web Worker 中可用。
此外,還需注意,performance 的建立和衡量都是同一環境下的。
即,若是你在主線程(或者其餘 worker)中建立了一個 performance,那麼它在另外的 worker 線程中是不可用的;反之亦然。
複製代碼

接下來,咱們先介紹一下 Performance API 的屬性:


Performance.navigation(操做相關)

該屬性是一個對象,有兩個屬性值,分別是 redirectCount(重定向次數)type(操做的類型)

redirectCount

該屬性值爲幾,就說明了當前頁面重定向了多少次;

type

type(0):當前頁面是經過點擊連接,書籤和表單提交,或者腳本操做,或者在url中直接輸入地址;

type(1):點擊刷新頁面按鈕或者經過Location.reload()方法顯示的頁面;

type(2):頁面經過歷史記錄和前進後退訪問時;

type(255):任何其餘方式


Performance.timing(延遲相關)

當前頁面中與時間相關的信息:

navigationStart

從同一個瀏覽器的上一個頁面卸載 unload 結束時的時間戳(精確到毫秒)

unloadEventStart

unload 事件執行時的時間戳。若是沒有上一個頁面,或者若是先前的頁面或所需的重定向之一不是同一個來源, 這個值會返回0

unloadEventEnd

unload 事件執行完的時間戳。若是沒有上一個頁面,或者若是先前的頁面或所需的重定向之一不是同一個來源, 這個值會返回0

redirectStart

第一個HTTP重定向開始時得時間戳。若是沒有上一個頁面,或者若是先前的頁面或所需的重定向之一不是同一個來源, 這個值會返回0

redirectEnd

最後一個HTTP重定向完成時(也就是說是HTTP響應的最後一個字節直接被收到的時間)的時間戳

fetchStart

表徵了瀏覽器準備好使用HTTP請求來獲取(fetch)文檔的時間戳。這個時間點會在檢查任何應用緩存以前

domainLookupStart

表徵了域名查詢開始的時間戳。若是使用了持續鏈接,或者這個信息存儲到了緩存或者本地資源上,這個值將和 PerformanceTiming.fetchStart 一致

domainLookupEnd

表徵了域名查詢結束的時間戳。若是使用了持續鏈接,或者這個信息存儲到了緩存或者本地資源上,這個值將和 PerformanceTiming.fetchStart 一致

connectStart

返回HTTP請求開始向服務器發送時的時間戳。若是使用持久鏈接,則返回值等同於 fetchStart 屬性的值

connectEnd

返回瀏覽器與服務器之間的鏈接創建時的時間戳。若是創建的是持久鏈接,則返回值等同於 fetchStart 屬性的值。鏈接創建指的是全部握手和認證過程所有結束

secureConnectionStart

返回瀏覽器與服務器開始安全連接的握手時的時間戳。若是當前網頁不要求安全鏈接,則返回0

requestStart

返回瀏覽器向服務器發出HTTP請求時(或開始讀取本地緩存時)的時間戳

responseStart

返回瀏覽器從服務器收到(或從本地緩存讀取)第一個字節時的時間戳。若是傳輸層在開始請求以後失敗而且鏈接被重開,該屬性將會被數製成新的請求的相對應的發起時間

responseEnd

返回瀏覽器從服務器收到(或從本地緩存讀取,或從本地資源讀取)最後一個字節時(若是在此以前HTTP鏈接已經關閉,則返回關閉時)的時間戳

domLoading

返回當前網頁DOM結構開始解析時(即 Document.readyState 屬性變爲 loading 、相應的 readystatechange 事件觸發時)的時間戳

domInteractive

返回當前網頁DOM結構結束解析、開始加載內嵌資源時(即 Document.readyState 屬性變爲 interactive 、相應的 readystatechange 事件觸發時)的時間戳

domContentLoadedEventStart

返回當解析器發送 DOMContentLoaded 事件,即全部須要被執行的腳本已經被解析時的時間戳

domContentLoadedEventEnd

返回當全部須要當即執行的腳本已經被執行(不論執行順序)時的時間戳

domComplete

返回當前文檔解析完成,即 Document.readyState 變爲 complete 且相對應的 readystatechange 被觸發時的時間戳

loadEventStart

返回該頁面下,load 事件被髮送時的時間戳。若是這個事件還未被髮送,它的值將會是0

loadEventEnd

返回當 load 事件結束,即加載事件完成時的時間戳。若是這個事件還未被髮送,或者還沒有完成,它的值將會是0


Performance.memory(js堆相關)

js堆有關的信息:

jsHeapSizeLimit

js堆大小限制

totalJSHeapSize

js堆總大小

usedJSHeapSize

使用了js堆的大小


Performance.timeOrigin(性能檢測開始時間)

這個屬性返回的是性能測量開始時的時間的高精度時間戳,number 類型

Performance 還有一個事件:


Performance.onresourcetimingbufferfull(性能緩存區已滿時回調)

這個事件當瀏覽器的資源時間性能緩衝區已滿時會觸發

下面介紹一下 Performance 對象的方法:


Performance.clearMarks()

將給定的 mark 從瀏覽器的性能輸入緩衝區中移除


Performance.clearMeasures()

將給定的 measure 從瀏覽器的性能輸入緩衝區中


Performance.clearResourceTimings()

從瀏覽器的性能數據緩衝區中移除全部 entryTyperesourceperformance entries


Performance.getEntries(PerformanceEntryFilterOptions)

PerformanceEntryFilterOptions 參數

可選參數,該參數是一個對象,可接受三個屬性:

  • nameperformance entry 的名字
  • entryTypeentry 類型. 合法的 entry 類型能夠從 PerformanceEntry.entryType 方法獲取
  • initiatorType:初始化資源的類型,例如:xmlhttprequestotherscript

Performance.getEntries 返回值

Performance.getEntries(PerformanceEntryFilterOptions) 返回值數組成員按 PerformanceEntry.startTime 時間順序排列

若是沒有符合 filter 條件的對象,那麼返回空數組. 若是不帶任何參數,返回所有 entries

因爲返回值是一個數組,因此咱們接下來說解一下每個數組項的每個屬性的意思:

  • connectEnd:鏈接結束時間
  • connectStart:鏈接開始時間
  • decodedBodySize:解碼的主體大小
  • domCompletedom 渲染完成時間
  • domContentLoadedEventEnddom 內容加載事件結束時間
  • domContentLoadedEventStartdom 內容加載事件開始時間
  • domInteractivedom 交互時間
  • domainLookupEnd:域查找結束時間
  • domainLookupStart:域查找開始時間
  • duration:事件耗時
  • encodedBodySize:編碼主體大小
  • entryType:資源輸入類型
  • fetchStart:獲取資源開始時間
  • initiatorType:發起人類型
  • loadEventEnd:加載事件結束時間
  • loadEventStart:加載事件開始時間
  • name:這裏通常就是當前請求的 url 的地址
  • nextHopProtocol:下一個跳轉協議
  • redirectCount:重定向次數
  • redirectEnd:重定向開始時間,若是沒有重定向,值爲0
  • redirectStart:重定向結束時間,若是沒有重定向,值爲0
  • requestStart:請求開始時間
  • responseEnd:響應結束時間
  • responseStart:響應開始時間
  • secureConnectionStart:安全鏈接開始時間
  • serverTiming:服務器時間
  • startTime:開始時間
  • transferSize:傳遞大小
  • type:該事件的類型
  • unloadEventEnd:卸載事件結束時間
  • unloadEventStart:卸載事件開始時間
  • workerStartworker 開始時間

Performance.mark(name)

根據給出 name 值,在瀏覽器的性能輸入緩衝區中建立一個相關的時間戳


Performance.measure(name, startMark, endMark)

這裏接收三個參數:

  • name:測量的名字
  • startMark:測量的開始標誌名字(也能夠是 PerformanceTiming 屬性的名稱)
  • endMark:測量的結束標誌名字(也能夠是 PerformanceTiming 屬性的名稱)

Performance.getEntriesByName(name, type)

這裏接收兩個參數:

  • name:測量的名字
  • type:測量的類型(frame, navigationresourcemarkmeasurepaint

Performance.getEntriesByType(type)

接收一個參數,type 同上面 Performance.getEntriesByName(name, type)type


Performance.now()

返回一個表示從性能測量時刻開始通過的毫秒數


Performance.setResourceTimingBufferSize(maxSize)

設置瀏覽器應在其性能條目緩衝區中保存的最大性能條目對象數


Performance.toJSON()

返回 Performance 對象的 JSON 對象


Performance API 的介紹也差很少了,瀏覽器的兼容性也是很不錯的:

基本上在咱們項目當中去作性能檢測是沒有問題的,畢竟咱們是確定不能把有關性能檢測的代碼打包到項目當中

Performance API 的簡單使用

這是我寫的一個小 demo ,大體的意思:

就是咱們在定時器執行前,添加了個標記 measure-start

在定時器執行後,又添加了個標記 measure-end

測量一下兩個標記之間的開始時間和持續時間 measure-list

最後清除全部 marks 的標誌位和 measures 的標誌位;

從這個小 demo 咱們就能看出來它的實用性和方便性,從這裏咱們就能夠看出來,Performance API 能夠橫跨不少個方法,去檢測它的調用時間,而 Performance 工具 就沒有辦法作到這一點

這就是我所說的相輔相成的關鍵點所在

結束語

到這裏,基本上 Performance 工具Performance API 的差別還有各自功能的介紹,就寫的差很少了

從上面的講解咱們能夠了解到,不一樣的東西,作着不一樣的事情,雖然沒有誰均可以知足部分需求,可是互相的配合,可讓東西作到更好

文中若是有講解不詳細的地方,或者說有講解的內容有錯誤的地方,還請你們指出,方便我作最快的改正,感謝每個認真看了文章看到這裏的朋友

下一篇文章,可能會有兩個選擇:

  • vue 和 react 經過 Performance 檢測到底誰的運行速度更快(精簡demo測試)
  • Audits 審計(精確到 Audits 審計報表文件每個字段)

你們若是有什麼想法,還請留言,感謝你們支持

相關文章
相關標籤/搜索