Chrome 64 版即將淘汰 chrome.loadTimes() API

沃爾頓 (Philip Walton)
Philip Walton

chrome.loadTimes() 是非標準 API,會向開發人員顯示載入指標和網路資訊,協助他們進一步瞭解網站的實際效能。

這個 API 於 2009 年實作,您可以在標準化 API 中找到所回報的所有實用資訊,例如:

這些標準化 API 是由多個瀏覽器供應商實作。因此,Chrome 64 版淘汰了 chrome.loadTimes()

已淘汰的 API

chrome.loadTimes() 函式會傳回單一物件,其中包含其所有載入和網路資訊。舉例來說,下列物件是在 www.google.com 上呼叫 chrome.loadTimes() 的結果:

{
  "requestTime": 1513186741.847,
  "startLoadTime": 1513186741.847,
  "commitLoadTime": 1513186742.637,
  "finishDocumentLoadTime": 1513186742.842,
  "finishLoadTime": 1513186743.582,
  "firstPaintTime": 1513186742.829,
  "firstPaintAfterLoadTime": 0,
  "navigationType": "Reload",
  "wasFetchedViaSpdy": true,
  "wasNpnNegotiated": true,
  "npnNegotiatedProtocol": "h2",
  "wasAlternateProtocolAvailable": false,
  "connectionInfo": "h2"
}

標準化替換品

您現在可以使用標準化 API 找到上述每個值。下表將每個值與其標準化 API 進行比對,以及下列各節的程式碼範例,說明如何在具有現代化對等項目的舊版 API 中取得每個值。

chrome.loadTimes() 功能 標準化 API 替換
requestTime 導覽時間 2
startLoadTime 導覽時間 2
commitLoadTime 導覽時間 2
finishDocumentLoadTime 導覽時間 2
finishLoadTime 導覽時間 2
firstPaintTime 繪製時間
firstPaintAfterLoadTime 不適用
navigationType 導覽時間 2
wasFetchedViaSpdy 導覽時間 2
wasNpnNegotiated 導覽時間 2
npnNegotiatedProtocol 導覽時間 2
wasAlternateProtocolAvailable 不適用
connectionInfo 導覽時間 2

下列程式碼範例會傳回 chrome.loadTimes() 傳回的值相等的值。不過,對於新的程式碼,不建議提供這些程式碼範例。原因為 chrome.loadTimes() 會指定以秒數為單位的Epoch 紀元時間值,而新的效能 API 通常以毫秒為單位回報相對於網頁時間來源的值,這對於進行效能分析時更為實用。

其中幾個範例也偏好使用 Performance Timeline 2 API (例如 performance.getEntriesByType()),但為舊版 Navigation Timing 1 API 提供備用選項,因為其支援更廣泛的瀏覽器。往後,建議使用 Performance Timeline API,這類 API 回報的精確度通常較高。

requestTime

function requestTime() {
  // If the browser supports the Navigation Timing 2 and HR Time APIs, use
  // them, otherwise fall back to the Navigation Timing 1 API.
  if (window.PerformanceNavigationTiming && performance.timeOrigin) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return (ntEntry.startTime + performance.timeOrigin) / 1000;
  } else {
    return performance.timing.navigationStart / 1000;
  }
}

startLoadTime

function startLoadTime() {
  // If the browser supports the Navigation Timing 2 and HR Time APIs, use
  // them, otherwise fall back to the Navigation Timing 1 API.
  if (window.PerformanceNavigationTiming && performance.timeOrigin) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return (ntEntry.startTime + performance.timeOrigin) / 1000;
  } else {
    return performance.timing.navigationStart / 1000;
  }
}

commitLoadTime

function commitLoadTime() {
  // If the browser supports the Navigation Timing 2 and HR Time APIs, use
  // them, otherwise fall back to the Navigation Timing 1 API.
  if (window.PerformanceNavigationTiming && performance.timeOrigin) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return (ntEntry.responseStart + performance.timeOrigin) / 1000;
  } else {
    return performance.timing.responseStart / 1000;
  }
}

finishDocumentLoadTime

function finishDocumentLoadTime() {
  // If the browser supports the Navigation Timing 2 and HR Time APIs, use
  // them, otherwise fall back to the Navigation Timing 1 API.
  if (window.PerformanceNavigationTiming && performance.timeOrigin) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return (ntEntry.domContentLoadedEventEnd + performance.timeOrigin) / 1000;
  } else {
    return performance.timing.domContentLoadedEventEnd / 1000;
  }
}

finishLoadTime

function finishLoadTime() {
  // If the browser supports the Navigation Timing 2 and HR Time APIs, use
  // them, otherwise fall back to the Navigation Timing 1 API.
  if (window.PerformanceNavigationTiming && performance.timeOrigin) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return (ntEntry.loadEventEnd + performance.timeOrigin) / 1000;
  } else {
    return performance.timing.loadEventEnd / 1000;
  }
}

firstPaintTime

function firstPaintTime() {
  if (window.PerformancePaintTiming) {
    const fpEntry = performance.getEntriesByType('paint')[0];
    return (fpEntry.startTime + performance.timeOrigin) / 1000;
  }
}

firstPaintAfterLoadTime

function firstPaintTimeAfterLoad() {
  // This was never actually implemented and always returns 0.
  return 0;
}
function navigationType() {
  if (window.PerformanceNavigationTiming) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return ntEntry.type;
  }
}

wasFetchedViaSpdy

function wasFetchedViaSpdy() {
  // SPDY is deprecated in favor of HTTP/2, but this implementation returns
  // true for HTTP/2 or HTTP2+QUIC/39 as well.
  if (window.PerformanceNavigationTiming) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return ['h2', 'hq'].includes(ntEntry.nextHopProtocol);
  }
}

wasNpnNegotiated

function wasNpnNegotiated() {
  // NPN is deprecated in favor of ALPN, but this implementation returns true
  // for HTTP/2 or HTTP2+QUIC/39 requests negotiated via ALPN.
  if (window.PerformanceNavigationTiming) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return ['h2', 'hq'].includes(ntEntry.nextHopProtocol);
  }
}

npnNegotiatedProtocol

function npnNegotiatedProtocol() {
  // NPN is deprecated in favor of ALPN, but this implementation returns the
  // HTTP/2 or HTTP2+QUIC/39 requests negotiated via ALPN.
  if (window.PerformanceNavigationTiming) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return ['h2', 'hq'].includes(ntEntry.nextHopProtocol) ?
        ntEntry.nextHopProtocol : 'unknown';
  }
}

wasAlternateProtocolAvailable

function wasAlternateProtocolAvailable() {
  // The Alternate-Protocol header is deprecated in favor of Alt-Svc
  // (https://www.mnot.net/blog/2016/03/09/alt-svc), so technically this
  // should always return false.
  return false;
}

connectionInfo

function connectionInfo() {
  if (window.PerformanceNavigationTiming) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return ntEntry.nextHopProtocol;
  }
}

移除計畫

chrome.loadTimes() API 將於 Chrome 64 版中淘汰,並預計於 2018 年下半年移除。開發人員應盡快遷移程式碼,以免資料遺失。

Intent to Deprecate | Chromestatus Tracker | Chromium 錯誤