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
); }
116 DOMTimeMilliSec
GetTimeToDOMContentFlushed() const {
117 return TimeStampToDOM(mDOMContentFlushed
);
120 DOMHighResTimeStamp
GetUnloadEventStartHighRes() {
121 mozilla::TimeStamp stamp
= GetUnloadEventStartTimeStamp();
122 if (stamp
.IsNull()) {
125 return TimeStampToDOMHighRes(stamp
);
127 DOMHighResTimeStamp
GetUnloadEventEndHighRes() {
128 mozilla::TimeStamp stamp
= GetUnloadEventEndTimeStamp();
129 if (stamp
.IsNull()) {
132 return TimeStampToDOMHighRes(stamp
);
134 DOMHighResTimeStamp
GetDomInteractiveHighRes() const {
135 return TimeStampToDOMHighRes(mDOMInteractive
);
137 DOMHighResTimeStamp
GetDomContentLoadedEventStartHighRes() const {
138 return TimeStampToDOMHighRes(mDOMContentLoadedEventStart
);
140 DOMHighResTimeStamp
GetDomContentLoadedEventEndHighRes() const {
141 return TimeStampToDOMHighRes(mDOMContentLoadedEventEnd
);
143 DOMHighResTimeStamp
GetDomCompleteHighRes() const {
144 return TimeStampToDOMHighRes(mDOMComplete
);
146 DOMHighResTimeStamp
GetLoadEventStartHighRes() const {
147 return TimeStampToDOMHighRes(mLoadEventStart
);
149 DOMHighResTimeStamp
GetLoadEventEndHighRes() const {
150 return TimeStampToDOMHighRes(mLoadEventEnd
);
153 enum class DocShellState
: uint8_t { eActive
, eInactive
};
155 void NotifyNavigationStart(DocShellState aDocShellState
);
156 void NotifyFetchStart(nsIURI
* aURI
, Type aNavigationType
);
157 // A restoration occurs when the document is loaded from the
158 // bfcache. This method sets the appropriate parameters of the
159 // navigation timing object in this case.
160 void NotifyRestoreStart();
161 void NotifyBeforeUnload();
162 void NotifyUnloadAccepted(nsIURI
* aOldURI
);
163 void NotifyUnloadEventStart();
164 void NotifyUnloadEventEnd();
165 void NotifyLoadEventStart();
166 void NotifyLoadEventEnd();
168 // Document changes state to 'loading' before connecting to timing
169 void SetDOMLoadingTimeStamp(nsIURI
* aURI
, mozilla::TimeStamp aValue
);
170 void NotifyDOMLoading(nsIURI
* aURI
);
171 void NotifyDOMInteractive(nsIURI
* aURI
);
172 void NotifyDOMComplete(nsIURI
* aURI
);
173 void NotifyDOMContentLoadedStart(nsIURI
* aURI
);
174 void NotifyDOMContentLoadedEnd(nsIURI
* aURI
);
176 static void TTITimeoutCallback(nsITimer
* aTimer
, void* aClosure
);
177 void TTITimeout(nsITimer
* aTimer
);
179 void NotifyLongTask(mozilla::TimeStamp aWhen
);
180 void NotifyNonBlankPaintForRootContentDocument();
181 void NotifyContentfulCompositeForRootContentDocument(
182 const mozilla::TimeStamp
& aCompositeEndTime
);
183 void NotifyLargestContentfulRenderForRootContentDocument(
184 const DOMHighResTimeStamp
& aRenderTime
);
185 void NotifyDOMContentFlushedForRootContentDocument();
186 void NotifyDocShellStateChanged(DocShellState aDocShellState
);
188 void MaybeAddLCPProfilerMarker(mozilla::MarkerInnerWindowId aInnerWindowID
);
190 DOMTimeMilliSec
TimeStampToDOM(mozilla::TimeStamp aStamp
) const;
192 inline DOMHighResTimeStamp
TimeStampToDOMHighRes(
193 mozilla::TimeStamp aStamp
) const {
194 if (aStamp
.IsNull()) {
197 mozilla::TimeDuration duration
= aStamp
- mNavigationStart
;
198 return duration
.ToMilliseconds();
201 // Called by the DocumentLoadListener before sending the timing information
202 // to the new content process.
203 void Anonymize(nsIURI
* aFinalURI
);
205 inline already_AddRefed
<nsDOMNavigationTiming
> CloneNavigationTime(
206 nsDocShell
* aDocShell
) const {
207 RefPtr
<nsDOMNavigationTiming
> timing
= new nsDOMNavigationTiming(aDocShell
);
208 timing
->mNavigationStartHighRes
= mNavigationStartHighRes
;
209 timing
->mNavigationStart
= mNavigationStart
;
210 return timing
.forget();
213 bool DocShellHasBeenActiveSinceNavigationStart() {
214 return mDocShellHasBeenActiveSinceNavigationStart
;
217 mozilla::TimeStamp
LoadEventEnd() { return mLoadEventEnd
; }
220 friend class nsDocShell
;
221 nsDOMNavigationTiming(nsDocShell
* aDocShell
, nsDOMNavigationTiming
* aOther
);
222 nsDOMNavigationTiming(const nsDOMNavigationTiming
&) = delete;
223 ~nsDOMNavigationTiming();
227 mozilla::TimeStamp
GetUnloadEventStartTimeStamp() const;
228 mozilla::TimeStamp
GetUnloadEventEndTimeStamp() const;
230 bool IsTopLevelContentDocumentInContentProcess() const;
232 // Should those be amended, the IPC serializer should be updated
234 mozilla::WeakPtr
<nsDocShell
> mDocShell
;
236 nsCOMPtr
<nsIURI
> mUnloadedURI
;
237 nsCOMPtr
<nsIURI
> mLoadedURI
;
238 nsCOMPtr
<nsITimer
> mTTITimer
;
240 Type mNavigationType
;
241 DOMHighResTimeStamp mNavigationStartHighRes
;
242 mozilla::TimeStamp mNavigationStart
;
243 mozilla::TimeStamp mNonBlankPaint
;
244 mozilla::TimeStamp mContentfulComposite
;
245 mozilla::TimeStamp mLargestContentfulRender
;
246 mozilla::TimeStamp mDOMContentFlushed
;
248 mozilla::TimeStamp mBeforeUnloadStart
;
249 mozilla::TimeStamp mUnloadStart
;
250 mozilla::TimeStamp mUnloadEnd
;
251 mozilla::TimeStamp mLoadEventStart
;
252 mozilla::TimeStamp mLoadEventEnd
;
254 mozilla::TimeStamp mDOMLoading
;
255 mozilla::TimeStamp mDOMInteractive
;
256 mozilla::TimeStamp mDOMContentLoadedEventStart
;
257 mozilla::TimeStamp mDOMContentLoadedEventEnd
;
258 mozilla::TimeStamp mDOMComplete
;
260 mozilla::TimeStamp mTTFI
;
262 bool mDocShellHasBeenActiveSinceNavigationStart
;
264 friend struct mozilla::ipc::IPDLParamTraits
<nsDOMNavigationTiming
*>;
267 // IPDL serializer. Please be aware of the caveats in sending across
268 // the information and the potential resulting data leakage.
269 // For now, this serializer is to only be used under a very narrowed scope
270 // so that only the starting times are ever set.
271 namespace mozilla::ipc
{
273 struct IPDLParamTraits
<nsDOMNavigationTiming
*> {
274 static void Write(IPC::MessageWriter
* aWriter
, IProtocol
* aActor
,
275 nsDOMNavigationTiming
* aParam
);
276 static bool Read(IPC::MessageReader
* aReader
, IProtocol
* aActor
,
277 RefPtr
<nsDOMNavigationTiming
>* aResult
);
280 } // namespace mozilla::ipc
282 #endif /* nsDOMNavigationTiming_h___ */