Bug 1344893 - Part 1: Report Navigation Timing into Telemetry. r?smaug
MozReview-Commit-ID: GiJigRLYHNV
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1783,17 +1783,17 @@ nsDocShell::MaybeInitTiming()
mScriptGlobal->AsOuter()->GetCurrentInnerWindow();
if (innerWin && innerWin->GetPerformance()) {
mTiming = innerWin->GetPerformance()->GetDOMTiming();
mBlankTiming = false;
}
}
if (!mTiming) {
- mTiming = new nsDOMNavigationTiming();
+ mTiming = new nsDOMNavigationTiming(this);
canBeReset = true;
}
mTiming->NotifyNavigationStart(
mIsActive ? nsDOMNavigationTiming::DocShellState::eActive
: nsDOMNavigationTiming::DocShellState::eInactive);
return canBeReset;
--- a/dom/base/nsDOMNavigationTiming.cpp
+++ b/dom/base/nsDOMNavigationTiming.cpp
@@ -5,28 +5,32 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsDOMNavigationTiming.h"
#include "GeckoProfiler.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "nsIScriptSecurityManager.h"
+#include "nsIDocShell.h"
+#include "nsIContentViewer.h"
#include "prtime.h"
#include "nsIURI.h"
#include "nsPrintfCString.h"
#include "mozilla/dom/PerformanceNavigation.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Telemetry.h"
using namespace mozilla;
-nsDOMNavigationTiming::nsDOMNavigationTiming()
+nsDOMNavigationTiming::nsDOMNavigationTiming(nsIDocShell* aDocShell)
{
Clear();
+
+ mDocShell = do_GetWeakReference(aDocShell);
}
nsDOMNavigationTiming::~nsDOMNavigationTiming()
{
}
void
nsDOMNavigationTiming::Clear()
@@ -122,16 +126,21 @@ nsDOMNavigationTiming::NotifyLoadEventSt
}
void
nsDOMNavigationTiming::NotifyLoadEventEnd()
{
if (!mLoadEventEndSet) {
mLoadEventEnd = DurationFromStart();
mLoadEventEndSet = true;
+
+ if (IsTopLevelContentDocument()) {
+ Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_LOAD_EVENT_MS,
+ mNavigationStartTimeStamp);
+ }
}
}
void
nsDOMNavigationTiming::SetDOMLoadingTimeStamp(nsIURI* aURI, TimeStamp aValue)
{
if (!mDOMLoadingSet) {
mLoadedURI = aURI;
@@ -142,36 +151,51 @@ nsDOMNavigationTiming::SetDOMLoadingTime
void
nsDOMNavigationTiming::NotifyDOMLoading(nsIURI* aURI)
{
if (!mDOMLoadingSet) {
mLoadedURI = aURI;
mDOMLoading = DurationFromStart();
mDOMLoadingSet = true;
+
+ if (IsTopLevelContentDocument()) {
+ Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_LOADING_MS,
+ mNavigationStartTimeStamp);
+ }
}
}
void
nsDOMNavigationTiming::NotifyDOMInteractive(nsIURI* aURI)
{
if (!mDOMInteractiveSet) {
mLoadedURI = aURI;
mDOMInteractive = DurationFromStart();
mDOMInteractiveSet = true;
+
+ if (IsTopLevelContentDocument()) {
+ Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_INTERACTIVE_MS,
+ mNavigationStartTimeStamp);
+ }
}
}
void
nsDOMNavigationTiming::NotifyDOMComplete(nsIURI* aURI)
{
if (!mDOMCompleteSet) {
mLoadedURI = aURI;
mDOMComplete = DurationFromStart();
mDOMCompleteSet = true;
+
+ if (IsTopLevelContentDocument()) {
+ Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_COMPLETE_MS,
+ mNavigationStartTimeStamp);
+ }
}
}
void
nsDOMNavigationTiming::NotifyDOMContentLoadedStart(nsIURI* aURI)
{
if (!mDOMContentLoadedEventStartSet) {
mLoadedURI = aURI;
@@ -182,16 +206,21 @@ nsDOMNavigationTiming::NotifyDOMContentL
void
nsDOMNavigationTiming::NotifyDOMContentLoadedEnd(nsIURI* aURI)
{
if (!mDOMContentLoadedEventEndSet) {
mLoadedURI = aURI;
mDOMContentLoadedEventEnd = DurationFromStart();
mDOMContentLoadedEventEndSet = true;
+
+ if (IsTopLevelContentDocument()) {
+ Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_CONTENT_LOADED_MS,
+ mNavigationStartTimeStamp);
+ }
}
}
void
nsDOMNavigationTiming::NotifyNonBlankPaintForRootContentDocument()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mNavigationStartTimeStamp.IsNull());
@@ -244,8 +273,30 @@ nsDOMNavigationTiming::GetUnloadEventEnd
{
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
nsresult rv = ssm->CheckSameOriginURI(mLoadedURI, mUnloadedURI, false);
if (NS_SUCCEEDED(rv)) {
return mUnloadEnd;
}
return 0;
}
+
+bool
+nsDOMNavigationTiming::IsTopLevelContentDocument() const
+{
+ if (!mDocShell) {
+ return false;
+ }
+ nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocShell);
+ if (!docShell) {
+ return false;
+ }
+ nsCOMPtr<nsIContentViewer> contentViewer;
+ Unused << docShell->GetContentViewer(getter_AddRefs(contentViewer));
+ if (!contentViewer) {
+ return false;
+ }
+ nsCOMPtr<nsIDocument> document = contentViewer->GetDocument();
+ if (!document) {
+ return false;
+ }
+ return document->GetTopLevelContentDocument() == document;
+}
--- a/dom/base/nsDOMNavigationTiming.h
+++ b/dom/base/nsDOMNavigationTiming.h
@@ -4,34 +4,36 @@
* 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/. */
#ifndef nsDOMNavigationTiming_h___
#define nsDOMNavigationTiming_h___
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
+#include "nsWeakPtr.h"
#include "mozilla/TimeStamp.h"
+class nsIDocShell;
class nsIURI;
typedef unsigned long long DOMTimeMilliSec;
typedef double DOMHighResTimeStamp;
class nsDOMNavigationTiming final
{
public:
enum Type {
TYPE_NAVIGATE = 0,
TYPE_RELOAD = 1,
TYPE_BACK_FORWARD = 2,
TYPE_RESERVED = 255,
};
- nsDOMNavigationTiming();
+ explicit nsDOMNavigationTiming(nsIDocShell* aDocShell);
NS_INLINE_DECL_REFCOUNTING(nsDOMNavigationTiming)
Type GetType() const
{
return mNavigationType;
}
@@ -115,16 +117,20 @@ public:
}
private:
nsDOMNavigationTiming(const nsDOMNavigationTiming &) = delete;
~nsDOMNavigationTiming();
void Clear();
+ bool IsTopLevelContentDocument() const;
+
+ nsWeakPtr mDocShell;
+
nsCOMPtr<nsIURI> mUnloadedURI;
nsCOMPtr<nsIURI> mLoadedURI;
Type mNavigationType;
DOMHighResTimeStamp mNavigationStartHighRes;
mozilla::TimeStamp mNavigationStartTimeStamp;
mozilla::TimeStamp mNonBlankPaintTimeStamp;
DOMTimeMilliSec DurationFromStart();
--- a/image/SVGDocumentWrapper.cpp
+++ b/image/SVGDocumentWrapper.cpp
@@ -356,17 +356,17 @@ SVGDocumentWrapper::SetupViewer(nsIReque
// The timeline(DocumentTimeline, used in CSS animation) of this SVG
// document needs this navigation timing object for time computation, such
// as to calculate current time stamp based on the start time of navigation
// time object.
//
// For a root document, DocShell would do these sort of things
// automatically. Since there is no DocShell for this wrapped SVG document,
// we must set it up manually.
- RefPtr<nsDOMNavigationTiming> timing = new nsDOMNavigationTiming();
+ RefPtr<nsDOMNavigationTiming> timing = new nsDOMNavigationTiming(nullptr);
timing->NotifyNavigationStart(nsDOMNavigationTiming::DocShellState::eInactive);
viewer->SetNavigationTiming(timing);
nsCOMPtr<nsIParser> parser = do_QueryInterface(listener);
NS_ENSURE_TRUE(parser, NS_ERROR_UNEXPECTED);
// XML-only, because this is for SVG content
nsCOMPtr<nsIContentSink> sink = parser->GetContentSink();
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -11289,10 +11289,55 @@
"bug_numbers": [1348113],
"expires_in_version": "60",
"kind": "exponential",
"low": 32,
"high": 750,
"n_buckets": 40,
"keyed": true,
"description": "Measures the number of milliseconds we spend waiting for sync message manager IPC messages to finish sending, keyed by message name. Note: only messages that wait for more than 500 microseconds are included in this probe."
+ },
+ "TIME_TO_DOM_LOADING_MS": {
+ "alert_emails": ["wpan@mozilla.com"],
+ "expires_in_version": "60",
+ "kind": "exponential",
+ "high": 50000,
+ "n_buckets": 100,
+ "bug_numbers": [1344893],
+ "description": "Time in milliseconds from navigationStart to domLoading."
+ },
+ "TIME_TO_DOM_INTERACTIVE_MS": {
+ "alert_emails": ["wpan@mozilla.com"],
+ "expires_in_version": "60",
+ "kind": "exponential",
+ "high": 50000,
+ "n_buckets": 100,
+ "bug_numbers": [1344893],
+ "description": "Time in milliseconds from navigationStart to domInteractive."
+ },
+ "TIME_TO_DOM_CONTENT_LOADED_MS": {
+ "alert_emails": ["wpan@mozilla.com"],
+ "expires_in_version": "60",
+ "kind": "exponential",
+ "high": 50000,
+ "n_buckets": 100,
+ "bug_numbers": [1344893],
+ "description": "Time in milliseconds from navigationStart to domContentLoadedEventEnd."
+ },
+ "TIME_TO_DOM_COMPLETE_MS": {
+ "alert_emails": ["wpan@mozilla.com"],
+ "expires_in_version": "60",
+ "kind": "exponential",
+ "high": 50000,
+ "n_buckets": 100,
+ "bug_numbers": [1344893],
+ "description": "Time in milliseconds from navigationStart to domComplete."
+ },
+ "TIME_TO_LOAD_EVENT_MS": {
+ "alert_emails": ["wpan@mozilla.com"],
+ "expires_in_version": "60",
+ "kind": "exponential",
+ "high": 50000,
+ "n_buckets": 100,
+ "bug_numbers": [1344893],
+ "description": "Time in milliseconds from navigationStart to loadEventEnd."
}
}