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 mozilla_dom_PerformanceMainThread_h
8 #define mozilla_dom_PerformanceMainThread_h
10 #include "Performance.h"
11 #include "PerformanceStorage.h"
12 #include "LargestContentfulPaint.h"
13 #include "nsTextFrame.h"
15 namespace mozilla::dom
{
17 class PerformanceNavigationTiming
;
18 class PerformanceEventTiming
;
20 using ImageLCPEntryMap
=
21 nsTHashMap
<LCPEntryHashEntry
, RefPtr
<LargestContentfulPaint
>>;
23 using TextFrameUnions
= nsTHashMap
<nsRefPtrHashKey
<Element
>, nsRect
>;
25 class PerformanceMainThread final
: public Performance
,
26 public PerformanceStorage
{
28 PerformanceMainThread(nsPIDOMWindowInner
* aWindow
,
29 nsDOMNavigationTiming
* aDOMTiming
,
30 nsITimedChannel
* aChannel
);
32 NS_DECL_ISUPPORTS_INHERITED
33 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(PerformanceMainThread
,
36 PerformanceStorage
* AsPerformanceStorage() override
{ return this; }
38 virtual PerformanceTiming
* Timing() override
;
40 virtual PerformanceNavigation
* Navigation() override
;
42 virtual void AddEntry(nsIHttpChannel
* channel
,
43 nsITimedChannel
* timedChannel
) override
;
45 // aData must be non-null.
46 virtual void AddEntry(const nsString
& entryName
,
47 const nsString
& initiatorType
,
48 UniquePtr
<PerformanceTimingData
>&& aData
) override
;
50 // aPerformanceTimingData must be non-null.
51 void AddRawEntry(UniquePtr
<PerformanceTimingData
> aPerformanceTimingData
,
52 const nsAString
& aInitiatorType
,
53 const nsAString
& aEntryName
);
54 virtual void SetFCPTimingEntry(PerformancePaintTiming
* aEntry
) override
;
55 bool HadFCPTimingEntry() const { return mFCPTiming
; }
57 void InsertEventTimingEntry(PerformanceEventTiming
*) override
;
58 void BufferEventTimingEntryIfNeeded(PerformanceEventTiming
*) override
;
59 void DispatchPendingEventTimingEntries() override
;
61 void BufferLargestContentfulPaintEntryIfNeeded(LargestContentfulPaint
*);
63 TimeStamp
CreationTimeStamp() const override
;
65 DOMHighResTimeStamp
CreationTime() const override
;
67 virtual void GetMozMemory(JSContext
* aCx
,
68 JS::MutableHandle
<JSObject
*> aObj
) override
;
70 virtual nsDOMNavigationTiming
* GetDOMTiming() const override
{
74 virtual uint64_t GetRandomTimelineSeed() override
{
75 return GetDOMTiming()->GetRandomTimelineSeed();
78 virtual nsITimedChannel
* GetChannel() const override
{ return mChannel
; }
80 // The GetEntries* methods need to be overriden in order to add the
81 // the document entry of type navigation.
82 virtual void GetEntries(nsTArray
<RefPtr
<PerformanceEntry
>>& aRetval
) override
;
84 // Return entries which qualify availableFromTimeline boolean check
85 virtual void GetEntriesByType(
86 const nsAString
& aEntryType
,
87 nsTArray
<RefPtr
<PerformanceEntry
>>& aRetval
) override
;
89 // There are entries that we don't want expose via performance, however
90 // we do want PerformanceObserver to get them
91 void GetEntriesByTypeForObserver(
92 const nsAString
& aEntryType
,
93 nsTArray
<RefPtr
<PerformanceEntry
>>& aRetval
) override
;
94 virtual void GetEntriesByName(
95 const nsAString
& aName
, const Optional
<nsAString
>& aEntryType
,
96 nsTArray
<RefPtr
<PerformanceEntry
>>& aRetval
) override
;
98 void UpdateNavigationTimingEntry() override
;
99 void QueueNavigationTimingEntry() override
;
100 void QueueLargestContentfulPaintEntry(LargestContentfulPaint
* aEntry
);
102 size_t SizeOfEventEntries(mozilla::MallocSizeOf aMallocSizeOf
) const override
;
104 static constexpr uint32_t kDefaultEventTimingBufferSize
= 150;
105 static constexpr uint32_t kDefaultEventTimingDurationThreshold
= 104;
106 static constexpr double kDefaultEventTimingMinDuration
= 16.0;
108 static constexpr uint32_t kMaxLargestContentfulPaintBufferSize
= 150;
110 class EventCounts
* EventCounts() override
;
112 bool IsGlobalObjectWindow() const override
{ return true; };
114 bool HasDispatchedInputEvent() const { return mHasDispatchedInputEvent
; }
116 void SetHasDispatchedScrollEvent();
117 bool HasDispatchedScrollEvent() const { return mHasDispatchedScrollEvent
; }
119 void ProcessElementTiming();
121 void AddImagesPendingRendering(ImagePendingRendering aImagePendingRendering
) {
122 mImagesPendingRendering
.AppendElement(aImagePendingRendering
);
125 void StoreImageLCPEntry(Element
* aElement
, imgRequestProxy
* aImgRequestProxy
,
126 LargestContentfulPaint
* aEntry
);
128 already_AddRefed
<LargestContentfulPaint
> GetImageLCPEntry(
129 Element
* aElement
, imgRequestProxy
* aImgRequestProxy
);
131 bool UpdateLargestContentfulPaintSize(double aSize
);
132 double GetLargestContentfulPaintSize() const {
133 return mLargestContentfulPaintSize
;
136 nsTHashMap
<nsRefPtrHashKey
<Element
>, nsRect
>& GetTextFrameUnions() {
137 return mTextFrameUnions
;
140 void FinalizeLCPEntriesForText();
142 void ClearGeneratedTempDataForLCP();
145 ~PerformanceMainThread();
147 void CreateNavigationTimingEntry();
149 void InsertUserEntry(PerformanceEntry
* aEntry
) override
;
151 DOMHighResTimeStamp
GetPerformanceTimingFromString(
152 const nsAString
& aTimingName
) override
;
154 void DispatchBufferFullEvent() override
;
156 RefPtr
<PerformanceNavigationTiming
> mDocEntry
;
157 RefPtr
<nsDOMNavigationTiming
> mDOMTiming
;
158 nsCOMPtr
<nsITimedChannel
> mChannel
;
159 RefPtr
<PerformanceTiming
> mTiming
;
160 RefPtr
<PerformanceNavigation
> mNavigation
;
161 RefPtr
<PerformancePaintTiming
> mFCPTiming
;
162 JS::Heap
<JSObject
*> mMozMemory
;
164 nsTArray
<RefPtr
<PerformanceEventTiming
>> mEventTimingEntries
;
165 nsTArray
<RefPtr
<LargestContentfulPaint
>> mLargestContentfulPaintEntries
;
167 AutoCleanLinkedList
<RefPtr
<PerformanceEventTiming
>>
168 mPendingEventTimingEntries
;
169 bool mHasDispatchedInputEvent
= false;
170 bool mHasDispatchedScrollEvent
= false;
172 RefPtr
<PerformanceEventTiming
> mFirstInputEvent
;
173 RefPtr
<PerformanceEventTiming
> mPendingPointerDown
;
176 void SetHasDispatchedInputEvent();
178 bool mHasQueuedRefreshdriverObserver
= false;
180 RefPtr
<class EventCounts
> mEventCounts
;
181 void IncEventCount(const nsAtom
* aType
);
183 PresShell
* GetPresShell();
185 nsTArray
<ImagePendingRendering
> mImagesPendingRendering
;
187 // The key is the pair of the element initiates the image loading
188 // and the imgRequestProxy of the image, and the value is
189 // the LCP entry for this image. When the image is
190 // completely loaded, we add it to mImageLCPEntryMap.
191 // Later, when the image is painted, we get the LCP entry from it
192 // to update the size and queue the entry if needed.
194 // When the initiating element is disconnected from the document,
195 // we keep the orphan entry because if the same memory address is
196 // reused by a different LCP candidate, it'll update
197 // mImageLCPEntryMap precedes before it tries to get the LCP entry.
198 ImageLCPEntryMap mImageLCPEntryMap
;
200 // Keeps track of the rendered size of the largest contentful paint that
201 // we have processed so far.
202 double mLargestContentfulPaintSize
= 0.0;
204 // When a text frame is painted, its area (relative to the
205 // containing block) is unioned with other text frames that
206 // belong to the same containing block.
207 // mTextFrameUnions's key is the containing block, and
208 // the value is the unioned area.
209 TextFrameUnions mTextFrameUnions
;
212 inline void ImplCycleCollectionTraverse(
213 nsCycleCollectionTraversalCallback
& aCallback
, ImageLCPEntryMap
& aField
,
214 const char* aName
, uint32_t aFlags
= 0) {
215 for (auto& entry
: aField
) {
216 RefPtr
<LargestContentfulPaint
>* lcpEntry
= entry
.GetModifiableData();
217 ImplCycleCollectionTraverse(aCallback
, *lcpEntry
, "ImageLCPEntryMap.mData",
222 inline void ImplCycleCollectionTraverse(
223 nsCycleCollectionTraversalCallback
& aCallback
, TextFrameUnions
& aField
,
224 const char* aName
, uint32_t aFlags
= 0) {
225 for (auto& entry
: aField
) {
226 ImplCycleCollectionTraverse(
227 aCallback
, entry
, "TextFrameUnions's key (nsRefPtrHashKey<Element>)",
232 } // namespace mozilla::dom
234 #endif // mozilla_dom_PerformanceMainThread_h