1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsDOMNavigationTiming_h___
8 #define nsDOMNavigationTiming_h___
11 #include "nsCOMArray.h"
12 #include "mozilla/WeakPtr.h"
13 #include "mozilla/RelativeTimeline.h"
14 #include "mozilla/TimeStamp.h"
15 #include "mozilla/BaseProfilerMarkersPrerequisites.h"
21 using DOMTimeMilliSec
= unsigned long long;
22 using DOMHighResTimeStamp
= double;
30 namespace mozilla::ipc
{
33 struct IPDLParamTraits
;
34 } // namespace mozilla::ipc
36 class nsDOMNavigationTiming final
: public mozilla::RelativeTimeline
{
41 TYPE_BACK_FORWARD
= 2,
45 explicit nsDOMNavigationTiming(nsDocShell
* aDocShell
);
47 NS_INLINE_DECL_REFCOUNTING(nsDOMNavigationTiming
)
49 Type
GetType() const { return mNavigationType
; }
51 inline DOMHighResTimeStamp
GetNavigationStartHighRes() const {
52 return mNavigationStartHighRes
;
55 DOMTimeMilliSec
GetNavigationStart() const {
56 return static_cast<int64_t>(GetNavigationStartHighRes());
59 mozilla::TimeStamp
GetNavigationStartTimeStamp() const {
60 return mNavigationStart
;
63 mozilla::TimeStamp
GetLoadEventStartTimeStamp() const {
64 return mLoadEventStart
;
67 mozilla::TimeStamp
GetDOMContentLoadedEventStartTimeStamp() const {
68 return mDOMContentLoadedEventStart
;
71 mozilla::TimeStamp
GetFirstContentfulCompositeTimeStamp() const {
72 return mContentfulComposite
;
75 mozilla::TimeStamp
GetLargestContentfulRenderTimeStamp() const {
76 return mLargestContentfulRender
;
79 DOMTimeMilliSec
GetUnloadEventStart() {
80 return TimeStampToDOM(GetUnloadEventStartTimeStamp());
83 DOMTimeMilliSec
GetUnloadEventEnd() {
84 return TimeStampToDOM(GetUnloadEventEndTimeStamp());
87 DOMTimeMilliSec
GetDomLoading() const { return TimeStampToDOM(mDOMLoading
); }
88 DOMTimeMilliSec
GetDomInteractive() const {
89 return TimeStampToDOM(mDOMInteractive
);
91 DOMTimeMilliSec
GetDomContentLoadedEventStart() const {
92 return TimeStampToDOM(mDOMContentLoadedEventStart
);
94 DOMTimeMilliSec
GetDomContentLoadedEventEnd() const {
95 return TimeStampToDOM(mDOMContentLoadedEventEnd
);
97 DOMTimeMilliSec
GetDomComplete() const {
98 return TimeStampToDOM(mDOMComplete
);
100 DOMTimeMilliSec
GetLoadEventStart() const {
101 return TimeStampToDOM(mLoadEventStart
);
103 DOMTimeMilliSec
GetLoadEventEnd() const {
104 return TimeStampToDOM(mLoadEventEnd
);
106 DOMTimeMilliSec
GetTimeToNonBlankPaint() const {
107 return TimeStampToDOM(mNonBlankPaint
);
109 DOMTimeMilliSec
GetTimeToContentfulComposite() const {
110 return TimeStampToDOM(mContentfulComposite
);
112 DOMTimeMilliSec
GetTimeToLargestContentfulRender() const {
113 return TimeStampToDOM(mLargestContentfulRender
);
115 DOMTimeMilliSec
GetTimeToTTFI() const { return TimeStampToDOM(mTTFI
); }
117 DOMHighResTimeStamp
GetUnloadEventStartHighRes() {
118 mozilla::TimeStamp stamp
= GetUnloadEventStartTimeStamp();
119 if (stamp
.IsNull()) {
122 return TimeStampToDOMHighRes(stamp
);
124 DOMHighResTimeStamp
GetUnloadEventEndHighRes() {
125 mozilla::TimeStamp stamp
= GetUnloadEventEndTimeStamp();
126 if (stamp
.IsNull()) {
129 return TimeStampToDOMHighRes(stamp
);
131 DOMHighResTimeStamp
GetDomInteractiveHighRes() const {
132 return TimeStampToDOMHighRes(mDOMInteractive
);
134 DOMHighResTimeStamp
GetDomContentLoadedEventStartHighRes() const {
135 return TimeStampToDOMHighRes(mDOMContentLoadedEventStart
);
137 DOMHighResTimeStamp
GetDomContentLoadedEventEndHighRes() const {
138 return TimeStampToDOMHighRes(mDOMContentLoadedEventEnd
);
140 DOMHighResTimeStamp
GetDomCompleteHighRes() const {
141 return TimeStampToDOMHighRes(mDOMComplete
);
143 DOMHighResTimeStamp
GetLoadEventStartHighRes() const {
144 return TimeStampToDOMHighRes(mLoadEventStart
);
146 DOMHighResTimeStamp
GetLoadEventEndHighRes() const {
147 return TimeStampToDOMHighRes(mLoadEventEnd
);
150 enum class DocShellState
: uint8_t { eActive
, eInactive
};
152 void NotifyNavigationStart(DocShellState aDocShellState
);
153 void NotifyFetchStart(nsIURI
* aURI
, Type aNavigationType
);
154 // A restoration occurs when the document is loaded from the
155 // bfcache. This method sets the appropriate parameters of the
156 // navigation timing object in this case.
157 void NotifyRestoreStart();
158 void NotifyBeforeUnload();
159 void NotifyUnloadAccepted(nsIURI
* aOldURI
);
160 void NotifyUnloadEventStart();
161 void NotifyUnloadEventEnd();
162 void NotifyLoadEventStart();
163 void NotifyLoadEventEnd();
165 // Document changes state to 'loading' before connecting to timing
166 void SetDOMLoadingTimeStamp(nsIURI
* aURI
, mozilla::TimeStamp aValue
);
167 void NotifyDOMLoading(nsIURI
* aURI
);
168 void NotifyDOMInteractive(nsIURI
* aURI
);
169 void NotifyDOMComplete(nsIURI
* aURI
);
170 void NotifyDOMContentLoadedStart(nsIURI
* aURI
);
171 void NotifyDOMContentLoadedEnd(nsIURI
* aURI
);
173 static void TTITimeoutCallback(nsITimer
* aTimer
, void* aClosure
);
174 void TTITimeout(nsITimer
* aTimer
);
176 void NotifyLongTask(mozilla::TimeStamp aWhen
);
177 void NotifyNonBlankPaintForRootContentDocument();
178 void NotifyContentfulCompositeForRootContentDocument(
179 const mozilla::TimeStamp
& aCompositeEndTime
);
180 void NotifyLargestContentfulRenderForRootContentDocument(
181 const DOMHighResTimeStamp
& aRenderTime
);
182 void NotifyDocShellStateChanged(DocShellState aDocShellState
);
184 void MaybeAddLCPProfilerMarker(mozilla::MarkerInnerWindowId aInnerWindowID
);
186 DOMTimeMilliSec
TimeStampToDOM(mozilla::TimeStamp aStamp
) const;
188 inline DOMHighResTimeStamp
TimeStampToDOMHighRes(
189 mozilla::TimeStamp aStamp
) const {
190 if (aStamp
.IsNull()) {
193 mozilla::TimeDuration duration
= aStamp
- mNavigationStart
;
194 return duration
.ToMilliseconds();
197 // Called by the DocumentLoadListener before sending the timing information
198 // to the new content process.
199 void Anonymize(nsIURI
* aFinalURI
);
201 inline already_AddRefed
<nsDOMNavigationTiming
> CloneNavigationTime(
202 nsDocShell
* aDocShell
) const {
203 RefPtr
<nsDOMNavigationTiming
> timing
= new nsDOMNavigationTiming(aDocShell
);
204 timing
->mNavigationStartHighRes
= mNavigationStartHighRes
;
205 timing
->mNavigationStart
= mNavigationStart
;
206 return timing
.forget();
209 bool DocShellHasBeenActiveSinceNavigationStart() const {
210 return mDocShellHasBeenActiveSinceNavigationStart
;
213 mozilla::TimeStamp
LoadEventEnd() { return mLoadEventEnd
; }
216 friend class nsDocShell
;
217 nsDOMNavigationTiming(nsDocShell
* aDocShell
, nsDOMNavigationTiming
* aOther
);
218 nsDOMNavigationTiming(const nsDOMNavigationTiming
&) = delete;
219 ~nsDOMNavigationTiming();
223 mozilla::TimeStamp
GetUnloadEventStartTimeStamp() const;
224 mozilla::TimeStamp
GetUnloadEventEndTimeStamp() const;
226 bool IsTopLevelContentDocumentInContentProcess() const;
228 // Should those be amended, the IPC serializer should be updated
230 mozilla::WeakPtr
<nsDocShell
> mDocShell
;
232 nsCOMPtr
<nsIURI
> mUnloadedURI
;
233 nsCOMPtr
<nsIURI
> mLoadedURI
;
234 nsCOMPtr
<nsITimer
> mTTITimer
;
236 Type mNavigationType
;
237 DOMHighResTimeStamp mNavigationStartHighRes
;
238 mozilla::TimeStamp mNavigationStart
;
239 mozilla::TimeStamp mNonBlankPaint
;
240 mozilla::TimeStamp mContentfulComposite
;
241 mozilla::TimeStamp mLargestContentfulRender
;
243 mozilla::TimeStamp mBeforeUnloadStart
;
244 mozilla::TimeStamp mUnloadStart
;
245 mozilla::TimeStamp mUnloadEnd
;
246 mozilla::TimeStamp mLoadEventStart
;
247 mozilla::TimeStamp mLoadEventEnd
;
249 mozilla::TimeStamp mDOMLoading
;
250 mozilla::TimeStamp mDOMInteractive
;
251 mozilla::TimeStamp mDOMContentLoadedEventStart
;
252 mozilla::TimeStamp mDOMContentLoadedEventEnd
;
253 mozilla::TimeStamp mDOMComplete
;
255 mozilla::TimeStamp mTTFI
;
257 bool mDocShellHasBeenActiveSinceNavigationStart
;
259 friend struct mozilla::ipc::IPDLParamTraits
<nsDOMNavigationTiming
*>;
262 // IPDL serializer. Please be aware of the caveats in sending across
263 // the information and the potential resulting data leakage.
264 // For now, this serializer is to only be used under a very narrowed scope
265 // so that only the starting times are ever set.
266 namespace mozilla::ipc
{
268 struct IPDLParamTraits
<nsDOMNavigationTiming
*> {
269 static void Write(IPC::MessageWriter
* aWriter
, IProtocol
* aActor
,
270 nsDOMNavigationTiming
* aParam
);
271 static bool Read(IPC::MessageReader
* aReader
, IProtocol
* aActor
,
272 RefPtr
<nsDOMNavigationTiming
>* aResult
);
275 } // namespace mozilla::ipc
277 #endif /* nsDOMNavigationTiming_h___ */