Chrome 64 zur Einstellung der chrome.loadTimes() API

Philip Walton
Philip Walton

chrome.loadTimes() ist eine nicht standardmäßige API, die Lademesswerte und Netzwerkinformationen für Entwickler bereitstellt, damit sie die Leistung ihrer Website in der Praxis besser nachvollziehen können.

Da diese API 2009 implementiert wurde, sind alle nützlichen Informationen, die sie meldet, in standardisierten APIs zu finden, wie z. B.:

Diese standardisierten APIs werden von mehreren Browseranbietern implementiert. Aus diesem Grund wird chrome.loadTimes() in Chrome 64 eingestellt.

Die eingestellte API

Die Funktion chrome.loadTimes() gibt ein einzelnes Objekt zurück, das alle zugehörigen Lade- und Netzwerkinformationen enthält. Das folgende Objekt ist beispielsweise das Ergebnis des Aufrufs von chrome.loadTimes() auf www.google.com:

{
  "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"
}

Standardisierte Ersetzungen

Sie können jetzt alle oben genannten Werte mithilfe standardisierter APIs finden. In der folgenden Tabelle wird jeder Wert der standardisierten API zugeordnet. Die folgenden Abschnitte zeigen Codebeispiele, wie die einzelnen Werte in der alten API mit modernen Äquivalenten abgerufen werden.

chrome.loadTimes() Funktion Standardisierter API-Ersatz
requestTime Navigationstiming 2
startLoadTime Navigationstiming 2
commitLoadTime Navigationstiming 2
finishDocumentLoadTime Navigationstiming 2
finishLoadTime Navigationstiming 2
firstPaintTime Paint-Timing
firstPaintAfterLoadTime
navigationType Navigationstiming 2
wasFetchedViaSpdy Navigationstiming 2
wasNpnNegotiated Navigationstiming 2
npnNegotiatedProtocol Navigationstiming 2
wasAlternateProtocolAvailable
connectionInfo Navigationstiming 2

In den folgenden Codebeispielen werden äquivalente Werte zurückgegeben wie die von chrome.loadTimes() zurückgegebenen Werte. Für neuen Code werden diese Codebeispiele jedoch nicht empfohlen. Der Grund dafür ist, dass chrome.loadTimes() Werte in der Epochenzeit in Sekunden angibt, während neue Performance APIs Werte normalerweise in Millisekunden relativ zum Zeitursprung einer Seite angeben, was für die Leistungsanalyse in der Regel nützlicher ist.

In einigen Beispielen werden auch Performance Timeline 2-APIs (z.B. performance.getEntriesByType()) bevorzugt, bieten jedoch Fallbacks für die ältere Navigation Timing 1 API, da sie eine breitere Browserunterstützung hat. Künftig werden Performance Timeline APIs bevorzugt. Sie werden in der Regel genauer angegeben.

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;
  }
}

Plan zur Entfernung von Inhalten

Die chrome.loadTimes() API wird in Chrome 64 eingestellt und Ende 2018 entfernt. Entwickler sollten ihren Code so schnell wie möglich migrieren, um Datenverluste zu vermeiden.

Abzustufen | Chromestatus-Tracker | Chromium-Fehler