chrome.loadTimes()
是非標準 API,會公開載入指標和
以便向開發人員
讓網站在現實環境中的成效表現
這個 API 是在 2009 年實作,因此報表可提供的所有實用資訊 各種標準化 API 中的指標,例如:
- 導覽時間 2
- 繪製時間
nextHopProtocol
除了 Navigation Timing 2 和 資源時間點 2。
這些標準化 API 是由多個瀏覽器供應商實作。身為
結果,chrome.loadTimes()
將在 Chrome 64 中淘汰。
已淘汰的 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 時間 (以秒為單位) 的值,而新的 Performance API 則是
報表時間通常以毫秒為單位
時間來源,通常會有
也有助於進行效能分析
有些範例也偏好使用 Performance Timeline 2 API (例如
performance.getEntriesByType()
),但為較舊的版本提供備用選項
Navigation Timing 1 API
支援更寬的瀏覽器日後建議使用 Performance Timeline 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;
}
navigationType
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 年年底移除開發人員應盡快遷移程式碼
以免資料遺失