本文中Performance API指的是Navigation Timing API。這並非一篇Navigation Timing API的介紹文章,而是我在使用中遇到的問題。後端
我在開發中遇到Navigation Timing API中的connectStart等時間節點並非標準時間戳,而是0或者一個很小的數值,致使指標數據計算出錯,尤爲是IOS設備。緣由以下:瀏覽器
IOS設備經過瀏覽器的前進後退按鈕進入的頁面,Navigation Timing API數據中connectStart,responseEnd等數據可能爲0或者是一個比較小的數值,並非對應時間點的時間戳。究其緣由,IOS設備經過緩存讀取頁面時,Navigation Timing的計算與安卓實現不一致。緩存
若是你還想了解下Navigation Timing API,能夠繼續往下看服務器
Navigation Timing API中包含所有的頁面加載中關鍵節點的時間,例如navigationStart,connectEnd,responseEnd等時間。 具體的相關API能夠去MDN查看, 瀏覽器支持程度也很是不錯,移動端IOS9及以上,Android4及以上都支持,桌面端IE9也都支持。dom
DNS時間 = domainLookupEnd - domainLookupStart TCP時間 = connectEnd - connectStart 後端時間 = responseEnd - connectEnd性能
白屏時間 = domInteractive - navigationStart 整屏時間 = loadEventEnd - navigationStart測試
解析dom樹耗時 = domComplete - domInteractive request請求耗時 = responseEnd - responseStartfetch
咱們團隊就是按照如上指標來作的各個時間的統計,作了各類測試,線下數據都沒什麼問題。上線了之後拿到的首批數據中,後端時間計算出來居然有負值,尤爲在IOS設備下,苦苦尋找緣由,終於發現問題所在。代理
IOS設備經過瀏覽器的前進後退按鈕進入的頁面,Navigation Timing API數據中connectStart,responseEnd等數據可能爲0或者是一個比較小的數值,並非對應時間點的時間戳。orm
根據Navigation Timing API的時間,是沒有辦法計算首屏時間的,首屏時間也並無嚴格的定義,咱們團隊採用的首屏時間以下
首屏時間 = (dom解析完畢 && 全部首屏圖片加載完畢 )- navigationStart
<table> <thead><tr> <th>屬性</th> <th>含義</th> </tr></thead> <tbody> <tr> <td>navigationStart</td> <td>準備加載新頁面的起始時間</td> </tr> <tr> <td>redirectStart</td> <td>若是發生了HTTP重定向,而且從導航開始,中間的每次重定向,都和當前文檔同域的話,就返回開始重定向的timing.fetchStart的值。其餘狀況,則返回0</td> </tr> <tr> <td>redirectEnd</td> <td>若是發生了HTTP重定向,而且從導航開始,中間的每次重定向,都和當前文檔同域的話,就返回最後一次重定向,接收到最後一個字節數據後的那個時間.其餘狀況則返回0</td> </tr> <tr> <td>fetchStart</td> <td>若是一個新的資源獲取被髮起,則 fetchStart必須返回用戶代理開始檢查其相關緩存的那個時間,其餘狀況則返回開始獲取該資源的時間</td> </tr> <tr> <td>domainLookupStart</td> <td>返回用戶代理對當前文檔所屬域進行DNS查詢開始的時間。若是此請求沒有DNS查詢過程,如長鏈接,資源cache,甚至是本地資源等。 那麼就返回 fetchStart的值</td> </tr> <tr> <td>domainLookupEnd</td> <td>返回用戶代理對結束對當前文檔所屬域進行DNS查詢的時間。若是此請求沒有DNS查詢過程,如長鏈接,資源cache,甚至是本地資源等。那麼就返回 fetchStart的值</td> </tr> <tr> <td>connectStart</td> <td>返回用戶代理向服務器服務器請求文檔,開始創建鏈接的那個時間,若是此鏈接是一個長鏈接,又或者直接從緩存中獲取資源(即沒有與服務器創建鏈接)。則返回domainLookupEnd的值</td> </tr> <tr> <td>(secureConnectionStart)</td> <td>可選特性。用戶代理若是沒有對應的東東,就要把這個設置爲undefined。若是有這個東東,而且是HTTPS協議,那麼就要返回開始SSL握手的那個時間。 若是不是HTTPS, 那麼就返回0</td> </tr> <tr> <td>connectEnd</td> <td>返回用戶代理向服務器服務器請求文檔,創建鏈接成功後的那個時間,若是此鏈接是一個長鏈接,又或者直接從緩存中獲取資源(即沒有與服務器創建鏈接)。則返回domainLookupEnd的值</td> </tr> <tr> <td>requestStart</td> <td>返回從服務器、緩存、本地資源等,開始請求文檔的時間</td> </tr> <tr> <td>responseStart</td> <td>返回用戶代理從服務器、緩存、本地資源中,接收到第一個字節數據的時間</td> </tr> <tr> <td>responseEnd</td> <td>返回用戶代理接收到最後一個字符的時間,和當前鏈接被關閉的時間中,更早的那個。一樣,文檔可能來自服務器、緩存、或本地資源</td> </tr> <tr> <td>domLoading</td> <td>返回用戶代理把其文檔的 "current document readiness" 設置爲 "loading"的時候</td> </tr> <tr> <td>domInteractive</td> <td>返回用戶代理把其文檔的 "current document readiness" 設置爲 "interactive"的時候.</td> </tr> <tr> <td>domContentLoadedEventStart</td> <td>返回文檔發生 DOMContentLoaded事件的時間</td> </tr> <tr> <td>domContentLoadedEventEnd</td> <td>文檔的DOMContentLoaded 事件的結束時間</td> </tr> <tr> <td>domComplete</td> <td>返回用戶代理把其文檔的 "current document readiness" 設置爲 "complete"的時候</td> </tr> <tr> <td>loadEventStart</td> <td>文檔觸發load事件的時間。若是load事件沒有觸發,那麼該接口就返回0</td> </tr> <tr> <td>loadEventEnd</td> <td>文檔觸發load事件結束後的時間。若是load事件沒有觸發,那麼該接口就返回0</td> </tr> </tbody> </table>