/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
void nsDOMNavigationTiming::NotifyFetchStart(nsIURI* aURI,
Type aNavigationType) {
mNavigationType = aNavigationType; // At the unload event time we don't really know the loading uri. // Need it for later check for unload timing access.
mLoadedURI = aURI;
}
void nsDOMNavigationTiming::TTITimeout(nsITimer* aTimer) { // Check TTI: see if it's been 5 seconds since the last Long Task
TimeStamp now = TimeStamp::Now();
MOZ_RELEASE_ASSERT(!mContentfulComposite.IsNull(), "TTI timeout with no contentful-composite?");
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
TimeStamp lastLongTaskEnded;
mainThread->GetLastLongNonIdleTaskEnd(&lastLongTaskEnded); // Window starts at mContentfulComposite; any long task before that is ignored if (lastLongTaskEnded.IsNull() || lastLongTaskEnded < mContentfulComposite) {
PAGELOAD_LOG(
("no longtask (last was %g ms before ContentfulComposite)",
lastLongTaskEnded.IsNull()
? 0
: (mContentfulComposite - lastLongTaskEnded).ToMilliseconds()));
lastLongTaskEnded = mContentfulComposite;
}
TimeDuration delta = now - lastLongTaskEnded;
PAGELOAD_LOG(("TTI delta: %g ms", delta.ToMilliseconds())); if (delta.ToMilliseconds() < TTI_WINDOW_SIZE_MS) { // Less than 5 seconds since the last long task or start of the window. // Schedule another check.
PAGELOAD_LOG(("TTI: waiting additional %g ms",
(TTI_WINDOW_SIZE_MS + 100) - delta.ToMilliseconds()));
aTimer->InitWithNamedFuncCallback(
TTITimeoutCallback, this,
(TTI_WINDOW_SIZE_MS + 100) -
delta.ToMilliseconds(), // slightly after the window ends
nsITimer::TYPE_ONE_SHOT_LOW_PRIORITY, "nsDOMNavigationTiming::TTITimeout"); return;
}
// To correctly implement TTI/TTFI as proposed, we'd need to not // fire it until there are no more than 2 network loads. By the // proposed definition, without that we're closer to // TimeToFirstInteractive. There are also arguments about what sort // of loads should qualify.
// XXX check number of network loads, and if > 2 mark to check if loads // decreases to 2 (or record that point and let the normal timer here // handle it)
// TTI has occurred! TTI is either FCP (if there are no longtasks and no // DCLEnd in the window that starts at FCP), or at the end of the last // Long Task or DOMContentLoadedEnd (whichever is later). lastLongTaskEnded // is >= FCP here.
if (mTTFI.IsNull()) { // lastLongTaskEnded is >= mContentfulComposite
mTTFI = (mDOMContentLoadedEventEnd.IsNull() ||
lastLongTaskEnded > mDOMContentLoadedEventEnd)
? lastLongTaskEnded
: mDOMContentLoadedEventEnd;
PAGELOAD_LOG(
("TTFI after %dms (LongTask was at %dms, DCL was %dms)", int((mTTFI - mNavigationStart).ToMilliseconds()),
lastLongTaskEnded.IsNull()
? 0
: int((lastLongTaskEnded - mNavigationStart).ToMilliseconds()),
mDOMContentLoadedEventEnd.IsNull()
? 0
: int((mDOMContentLoadedEventEnd - mNavigationStart)
.ToMilliseconds())));
} // XXX Implement TTI via check number of network loads, and if > 2 mark // to check if loads decreases to 2 (or record that point and let the // normal timer here handle it)
mTTITimer = nullptr;
if (profiler_thread_is_being_profiled_for_markers() ||
PAGELOAD_LOG_ENABLED()) {
TimeDuration elapsed = mTTFI - mNavigationStart;
MOZ_ASSERT(elapsed.ToMilliseconds() > 0);
TimeDuration elapsedLongTask =
lastLongTaskEnded.IsNull() ? 0 : lastLongTaskEnded - mNavigationStart;
nsPrintfCString marker( "TTFI after %dms (LongTask was at %dms) for URL %s", int(elapsed.ToMilliseconds()), int(elapsedLongTask.ToMilliseconds()),
nsContentUtils::TruncatedURLForDisplay(mLoadedURI).get());
if (profiler_thread_is_being_profiled_for_markers() ||
PAGELOAD_LOG_ENABLED()) {
TimeDuration elapsed = mContentfulComposite - mNavigationStart;
nsPrintfCString marker( "Contentful composite after %dms for URL %s, %s", int(elapsed.ToMilliseconds()),
nsContentUtils::TruncatedURLForDisplay(mLoadedURI).get(),
mDocShellHasBeenActiveSinceNavigationStart
? "foreground tab"
: "this tab was inactive some of the time between navigation start " "and first non-blank paint");
PAGELOAD_LOG(("%s", marker.get()));
PROFILER_MARKER_TEXT( "FirstContentfulComposite", DOM,
MarkerOptions(
MarkerTiming::Interval(mNavigationStart, mContentfulComposite),
MarkerInnerWindowIdFromDocShell(mDocShell)),
marker);
}
if (!mTTITimer) {
mTTITimer = NS_NewTimer();
}
// TTI is first checked 5 seconds after the FCP (non-blank-paint is very close // to FCP).
mTTITimer->InitWithNamedFuncCallback(TTITimeoutCallback, this,
TTI_WINDOW_SIZE_MS,
nsITimer::TYPE_ONE_SHOT_LOW_PRIORITY, "nsDOMNavigationTiming::TTITimeout");
if (mDocShellHasBeenActiveSinceNavigationStart) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_FIRST_CONTENTFUL_PAINT_MS,
mNavigationStart, mContentfulComposite);
}
}
// This can get called multiple times and updates over time.
mLargestContentfulRender =
mNavigationStart + TimeDuration::FromMilliseconds(aRenderTime);
}
void nsDOMNavigationTiming::MaybeAddLCPProfilerMarker(
MarkerInnerWindowId aInnerWindowID) { // This method might get called from outside of the main thread, so can't // check `profiler_thread_is_being_profiled_for_markers()` here. if (!profiler_is_active_and_unpaused()) { return;
}
TimeDuration elapsed = lcpTime - navStartTime;
nsPrintfCString marker("Largest contentful paint after %dms", int(elapsed.ToMilliseconds()));
PROFILER_MARKER_TEXT( "LargestContentfulPaint", DOM, // Putting this marker to the main thread even if it's called from another // one.
MarkerOptions(MarkerThreadId::MainThread(),
MarkerTiming::Interval(navStartTime, lcpTime),
std::move(aInnerWindowID)),
marker);
}
mozilla::TimeStamp nsDOMNavigationTiming::GetUnloadEventStartTimeStamp() const {
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); // todo: if you intend to update CheckSameOriginURI to log the error to the // console you also need to update the 'aFromPrivateWindow' argument.
nsresult rv = ssm->CheckSameOriginURI(mLoadedURI, mUnloadedURI, false, false); if (NS_SUCCEEDED(rv)) { return mUnloadStart;
} return mozilla::TimeStamp();
}
mozilla::TimeStamp nsDOMNavigationTiming::GetUnloadEventEndTimeStamp() const {
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); // todo: if you intend to update CheckSameOriginURI to log the error to the // console you also need to update the 'aFromPrivateWindow' argument.
nsresult rv = ssm->CheckSameOriginURI(mLoadedURI, mUnloadedURI, false, false); if (NS_SUCCEEDED(rv)) { return mUnloadEnd;
} return mozilla::TimeStamp();
}
bool nsDOMNavigationTiming::IsTopLevelContentDocumentInContentProcess() const { if (!mDocShell) { returnfalse;
} if (!XRE_IsContentProcess()) { returnfalse;
} return mDocShell->GetBrowsingContext()->IsTopContent();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.