Bug 1191943 P1 Implement PerformanceResourceTiming.workerStart. r=asuth

This commit is contained in:
Ben Kelly 2017-10-06 09:04:54 -07:00
parent c3d51e73b0
commit f9e5ee1ee2
5 changed files with 81 additions and 26 deletions

View File

@ -71,8 +71,22 @@ PerformanceResourceTiming::~PerformanceResourceTiming()
DOMHighResTimeStamp DOMHighResTimeStamp
PerformanceResourceTiming::StartTime() const PerformanceResourceTiming::StartTime() const
{ {
DOMHighResTimeStamp startTime = mTiming->RedirectStartHighRes(); // Force the start time to be the earliest of:
return startTime ? startTime : mTiming->FetchStartHighRes(); // - RedirectStart
// - WorkerStart
// - AsyncOpen
// Ignore zero values. The RedirectStart and WorkerStart values
// can come from earlier redirected channels prior to the AsyncOpen
// time being recorded.
DOMHighResTimeStamp redirect = mTiming->RedirectStartHighRes();
redirect = redirect ? redirect : DBL_MAX;
DOMHighResTimeStamp worker = mTiming->WorkerStartHighRes();
worker = worker ? worker : DBL_MAX;
DOMHighResTimeStamp asyncOpen = mTiming->AsyncOpenHighRes();
return std::min(asyncOpen, std::min(redirect, worker));
} }
JSObject* JSObject*

View File

@ -63,6 +63,12 @@ public:
mNextHopProtocol = aNextHopProtocol; mNextHopProtocol = aNextHopProtocol;
} }
DOMHighResTimeStamp WorkerStart() const {
return mTiming && mTiming->TimingAllowed()
? mTiming->WorkerStartHighRes()
: 0;
}
DOMHighResTimeStamp FetchStart() const { DOMHighResTimeStamp FetchStart() const {
return mTiming return mTiming
? mTiming->FetchStartHighRes() ? mTiming->FetchStartHighRes()

View File

@ -71,6 +71,7 @@ PerformanceTiming::InitializeTimingInfo(nsITimedChannel* aChannel)
{ {
if (aChannel) { if (aChannel) {
aChannel->GetAsyncOpen(&mAsyncOpen); aChannel->GetAsyncOpen(&mAsyncOpen);
aChannel->GetDispatchFetchEventStart(&mWorkerStart);
aChannel->GetAllRedirectsSameOrigin(&mAllRedirectsSameOrigin); aChannel->GetAllRedirectsSameOrigin(&mAllRedirectsSameOrigin);
aChannel->GetRedirectCount(&mRedirectCount); aChannel->GetRedirectCount(&mRedirectCount);
aChannel->GetRedirectStart(&mRedirectStart); aChannel->GetRedirectStart(&mRedirectStart);
@ -86,30 +87,38 @@ PerformanceTiming::InitializeTimingInfo(nsITimedChannel* aChannel)
aChannel->GetResponseEnd(&mResponseEnd); aChannel->GetResponseEnd(&mResponseEnd);
aChannel->GetCacheReadEnd(&mCacheReadEnd); aChannel->GetCacheReadEnd(&mCacheReadEnd);
// the performance timing api essentially requires that the event timestamps // The performance timing api essentially requires that the event timestamps
// are >= asyncOpen().. but in truth the browser engages in a number of // have a strict relation with each other. The truth, however, is the browser
// speculative activities that sometimes mean connections and lookups begin // engages in a number of speculative activities that sometimes mean connections
// earlier. Workaround that here by just using asyncOpen as the minimum // and lookups begin at different times. Workaround that here by clamping
// timestamp for dns and connection info. // these values to what we expect FetchStart to be. This means the later of
// AsyncOpen or WorkerStart times.
if (!mAsyncOpen.IsNull()) { if (!mAsyncOpen.IsNull()) {
if (!mDomainLookupStart.IsNull() && mDomainLookupStart < mAsyncOpen) { // We want to clamp to the expected FetchStart value. This is later of
mDomainLookupStart = mAsyncOpen; // the AsyncOpen and WorkerStart values.
const TimeStamp* clampTime = &mAsyncOpen;
if (!mWorkerStart.IsNull() && mWorkerStart > mAsyncOpen) {
clampTime = &mWorkerStart;
} }
if (!mDomainLookupEnd.IsNull() && mDomainLookupEnd < mAsyncOpen) { if (!mDomainLookupStart.IsNull() && mDomainLookupStart < *clampTime) {
mDomainLookupEnd = mAsyncOpen; mDomainLookupStart = *clampTime;
} }
if (!mConnectStart.IsNull() && mConnectStart < mAsyncOpen) { if (!mDomainLookupEnd.IsNull() && mDomainLookupEnd < *clampTime) {
mConnectStart = mAsyncOpen; mDomainLookupEnd = *clampTime;
} }
if (!mSecureConnectionStart.IsNull() && mSecureConnectionStart < mAsyncOpen) { if (!mConnectStart.IsNull() && mConnectStart < *clampTime) {
mSecureConnectionStart = mAsyncOpen; mConnectStart = *clampTime;
} }
if (!mConnectEnd.IsNull() && mConnectEnd < mAsyncOpen) { if (!mSecureConnectionStart.IsNull() && mSecureConnectionStart < *clampTime) {
mConnectEnd = mAsyncOpen; mSecureConnectionStart = *clampTime;
}
if (!mConnectEnd.IsNull() && mConnectEnd < *clampTime) {
mConnectEnd = *clampTime;
} }
} }
} }
@ -129,9 +138,13 @@ PerformanceTiming::FetchStartHighRes()
} }
MOZ_ASSERT(!mAsyncOpen.IsNull(), "The fetch start time stamp should always be " MOZ_ASSERT(!mAsyncOpen.IsNull(), "The fetch start time stamp should always be "
"valid if the performance timing is enabled"); "valid if the performance timing is enabled");
mFetchStart = (!mAsyncOpen.IsNull()) if (!mAsyncOpen.IsNull()) {
? TimeStampToDOMHighRes(mAsyncOpen) if (!mWorkerStart.IsNull() && mWorkerStart > mAsyncOpen) {
: 0.0; mFetchStart = TimeStampToDOMHighRes(mWorkerStart);
} else {
mFetchStart = TimeStampToDOMHighRes(mAsyncOpen);
}
}
} }
return mFetchStart; return mFetchStart;
} }
@ -205,6 +218,26 @@ PerformanceTiming::ShouldReportCrossOriginRedirect() const
return (mRedirectCount != 0) && mReportCrossOriginRedirect; return (mRedirectCount != 0) && mReportCrossOriginRedirect;
} }
DOMHighResTimeStamp
PerformanceTiming::AsyncOpenHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting() || mAsyncOpen.IsNull()) {
return mZeroTime;
}
return TimeStampToDOMHighRes(mAsyncOpen);
}
DOMHighResTimeStamp
PerformanceTiming::WorkerStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting() || mWorkerStart.IsNull()) {
return mZeroTime;
}
return TimeStampToDOMHighRes(mWorkerStart);
}
/** /**
* RedirectStartHighRes() is used by both the navigation timing and the * RedirectStartHighRes() is used by both the navigation timing and the
* resource timing. Since, navigation timing and resource timing check and * resource timing. Since, navigation timing and resource timing check and

View File

@ -157,7 +157,12 @@ public:
// the timing-allow-origin check in HttpBaseChannel::TimingAllowCheck // the timing-allow-origin check in HttpBaseChannel::TimingAllowCheck
bool ShouldReportCrossOriginRedirect() const; bool ShouldReportCrossOriginRedirect() const;
// The last channel's AsyncOpen time. This may occur before the FetchStart
// in some cases.
DOMHighResTimeStamp AsyncOpenHighRes();
// High resolution (used by resource timing) // High resolution (used by resource timing)
DOMHighResTimeStamp WorkerStartHighRes();
DOMHighResTimeStamp FetchStartHighRes(); DOMHighResTimeStamp FetchStartHighRes();
DOMHighResTimeStamp RedirectStartHighRes(); DOMHighResTimeStamp RedirectStartHighRes();
DOMHighResTimeStamp RedirectEndHighRes(); DOMHighResTimeStamp RedirectEndHighRes();
@ -273,6 +278,7 @@ private:
DOMHighResTimeStamp mZeroTime; DOMHighResTimeStamp mZeroTime;
TimeStamp mAsyncOpen; TimeStamp mAsyncOpen;
TimeStamp mWorkerStart;
TimeStamp mRedirectStart; TimeStamp mRedirectStart;
TimeStamp mRedirectEnd; TimeStamp mRedirectEnd;
TimeStamp mDomainLookupStart; TimeStamp mDomainLookupStart;

View File

@ -4,7 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. * You can obtain one at http://mozilla.org/MPL/2.0/.
* *
* The origin of this IDL file is * The origin of this IDL file is
* http://w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming * https://w3c.github.io/resource-timing/#performanceresourcetiming
* *
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply. * liability, trademark and document use rules apply.
@ -12,14 +12,10 @@
interface PerformanceResourceTiming : PerformanceEntry interface PerformanceResourceTiming : PerformanceEntry
{ {
// A string with the name of that element that initiated the load.
// If the initiator is a CSS resource, the initiatorType attribute must return
// the string "css".
// If the initiator is an XMLHttpRequest object, the initiatorType attribute
// must return the string "xmlhttprequest".
readonly attribute DOMString initiatorType; readonly attribute DOMString initiatorType;
readonly attribute DOMString nextHopProtocol; readonly attribute DOMString nextHopProtocol;
readonly attribute DOMHighResTimeStamp workerStart;
readonly attribute DOMHighResTimeStamp redirectStart; readonly attribute DOMHighResTimeStamp redirectStart;
readonly attribute DOMHighResTimeStamp redirectEnd; readonly attribute DOMHighResTimeStamp redirectEnd;
readonly attribute DOMHighResTimeStamp fetchStart; readonly attribute DOMHighResTimeStamp fetchStart;