OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * Copyright (C) 2012 Intel Inc. All rights reserved. | 3 * Copyright (C) 2012 Intel Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 14 matching lines...) Expand all Loading... | |
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 #include "core/timing/PerformanceBase.h" | 32 #include "core/timing/PerformanceBase.h" |
33 | 33 |
34 #include "core/dom/Document.h" | 34 #include "core/dom/Document.h" |
35 #include "core/dom/DocumentTiming.h" | |
36 #include "core/dom/Element.h" | |
35 #include "core/events/Event.h" | 37 #include "core/events/Event.h" |
38 #include "core/frame/LocalFrame.h" | |
36 #include "core/frame/UseCounter.h" | 39 #include "core/frame/UseCounter.h" |
40 #include "core/loader/DocumentLoadTiming.h" | |
41 #include "core/loader/DocumentLoader.h" | |
37 #include "core/timing/PerformanceLongTaskTiming.h" | 42 #include "core/timing/PerformanceLongTaskTiming.h" |
43 #include "core/timing/PerformanceNavigationTiming.h" | |
38 #include "core/timing/PerformanceObserver.h" | 44 #include "core/timing/PerformanceObserver.h" |
39 #include "core/timing/PerformanceResourceTiming.h" | 45 #include "core/timing/PerformanceResourceTiming.h" |
40 #include "core/timing/PerformanceUserTiming.h" | 46 #include "core/timing/PerformanceUserTiming.h" |
47 #include "platform/RuntimeEnabledFeatures.h" | |
41 #include "platform/network/ResourceTimingInfo.h" | 48 #include "platform/network/ResourceTimingInfo.h" |
42 #include "platform/weborigin/SecurityOrigin.h" | 49 #include "platform/weborigin/SecurityOrigin.h" |
43 #include "wtf/CurrentTime.h" | 50 #include "wtf/CurrentTime.h" |
44 #include <algorithm> | 51 #include <algorithm> |
45 | 52 |
46 namespace blink { | 53 namespace blink { |
47 | 54 |
55 namespace { | |
56 const DocumentLoader* documentLoader(LocalFrame* frame) { | |
57 if (!frame) | |
58 return nullptr; | |
59 return frame->loader().documentLoader(); | |
60 } | |
61 | |
62 const DocumentLoadTiming* documentLoadTiming(LocalFrame* frame) { | |
63 const DocumentLoader* loader = documentLoader(frame); | |
64 if (!loader) | |
65 return nullptr; | |
66 return &loader->timing(); | |
67 } | |
68 | |
69 const DocumentTiming* documentTiming(LocalFrame* frame) { | |
70 if (!frame) | |
71 return nullptr; | |
72 | |
73 Document* document = frame->document(); | |
74 if (!document) | |
75 return nullptr; | |
76 | |
77 return &document->timing(); | |
78 } | |
kinuko
2016/11/06 15:16:43
Not really sure if adding these helper methods are
sunjian
2016/11/08 02:10:18
Done.
| |
79 | |
80 AtomicString getNavigationType(LocalFrame* frame) { | |
81 if (!frame) | |
82 return "navigate"; | |
83 | |
84 DocumentLoader* documentLoader = frame->loader().documentLoader(); | |
85 if (!documentLoader) | |
86 return "navigate"; | |
87 | |
88 switch (documentLoader->getNavigationType()) { | |
89 case NavigationTypeReload: | |
90 return "reload"; | |
91 case NavigationTypeBackForward: | |
92 return "back_forward"; | |
93 default: | |
94 return "navigate"; | |
kinuko
2016/11/06 15:16:43
Do these need to use AtomicString? Calling this s
sunjian
2016/11/08 02:10:19
Done.
| |
95 } | |
96 } | |
97 } | |
kinuko
2016/11/06 15:16:43
nit: } // namespace
sunjian
2016/11/08 02:10:19
No need anymore.
| |
98 | |
48 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>; | 99 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>; |
49 | 100 |
50 static const size_t defaultResourceTimingBufferSize = 150; | 101 static const size_t defaultResourceTimingBufferSize = 150; |
51 static const size_t defaultFrameTimingBufferSize = 150; | 102 static const size_t defaultFrameTimingBufferSize = 150; |
52 | 103 |
53 PerformanceBase::PerformanceBase(double timeOrigin) | 104 PerformanceBase::PerformanceBase(double timeOrigin) |
54 : m_frameTimingBufferSize(defaultFrameTimingBufferSize), | 105 : m_frameTimingBufferSize(defaultFrameTimingBufferSize), |
55 m_resourceTimingBufferSize(defaultResourceTimingBufferSize), | 106 m_resourceTimingBufferSize(defaultResourceTimingBufferSize), |
107 m_navigationTiming(nullptr), | |
56 m_userTiming(nullptr), | 108 m_userTiming(nullptr), |
57 m_timeOrigin(timeOrigin), | 109 m_timeOrigin(timeOrigin), |
58 m_observerFilterOptions(PerformanceEntry::Invalid), | 110 m_observerFilterOptions(PerformanceEntry::Invalid), |
59 m_deliverObservationsTimer( | 111 m_deliverObservationsTimer( |
60 this, | 112 this, |
61 &PerformanceBase::deliverObservationsTimerFired) {} | 113 &PerformanceBase::deliverObservationsTimerFired) {} |
62 | 114 |
63 PerformanceBase::~PerformanceBase() {} | 115 PerformanceBase::~PerformanceBase() {} |
64 | 116 |
65 const AtomicString& PerformanceBase::interfaceName() const { | 117 const AtomicString& PerformanceBase::interfaceName() const { |
66 return EventTargetNames::Performance; | 118 return EventTargetNames::Performance; |
67 } | 119 } |
68 | 120 |
69 PerformanceTiming* PerformanceBase::timing() const { | 121 PerformanceTiming* PerformanceBase::timing() const { |
70 return nullptr; | 122 return nullptr; |
71 } | 123 } |
72 | 124 |
73 PerformanceEntryVector PerformanceBase::getEntries() const { | 125 PerformanceEntryVector PerformanceBase::getEntries() const { |
74 PerformanceEntryVector entries; | 126 PerformanceEntryVector entries; |
75 | 127 |
76 entries.appendVector(m_resourceTimingBuffer); | 128 entries.appendVector(m_resourceTimingBuffer); |
129 if (RuntimeEnabledFeatures::performanceNavigationTimingEnabled()) | |
130 entries.append(m_navigationTiming); | |
77 entries.appendVector(m_frameTimingBuffer); | 131 entries.appendVector(m_frameTimingBuffer); |
78 | 132 |
79 if (m_userTiming) { | 133 if (m_userTiming) { |
80 entries.appendVector(m_userTiming->getMarks()); | 134 entries.appendVector(m_userTiming->getMarks()); |
81 entries.appendVector(m_userTiming->getMeasures()); | 135 entries.appendVector(m_userTiming->getMeasures()); |
82 } | 136 } |
83 | 137 |
84 std::sort(entries.begin(), entries.end(), | 138 std::sort(entries.begin(), entries.end(), |
85 PerformanceEntry::startTimeCompareLessThan); | 139 PerformanceEntry::startTimeCompareLessThan); |
86 return entries; | 140 return entries; |
87 } | 141 } |
88 | 142 |
89 PerformanceEntryVector PerformanceBase::getEntriesByType( | 143 PerformanceEntryVector PerformanceBase::getEntriesByType( |
90 const String& entryType) { | 144 const String& entryType) { |
91 PerformanceEntryVector entries; | 145 PerformanceEntryVector entries; |
92 PerformanceEntry::EntryType type = | 146 PerformanceEntry::EntryType type = |
93 PerformanceEntry::toEntryTypeEnum(entryType); | 147 PerformanceEntry::toEntryTypeEnum(entryType); |
94 | 148 |
95 switch (type) { | 149 switch (type) { |
96 case PerformanceEntry::Invalid: | 150 case PerformanceEntry::Invalid: |
97 return entries; | 151 return entries; |
98 case PerformanceEntry::LongTask: | 152 case PerformanceEntry::LongTask: |
99 // Unsupported for LongTask. Per the spec, Long task entries can only be | 153 // Unsupported for LongTask. Per the spec, Long task entries can only be |
100 // accessed via Performance Observer. No separate buffer is maintained. | 154 // accessed via Performance Observer. No separate buffer is maintained. |
101 return entries; | 155 return entries; |
102 case PerformanceEntry::Resource: | 156 case PerformanceEntry::Resource: |
103 for (const auto& resource : m_resourceTimingBuffer) | 157 for (const auto& resource : m_resourceTimingBuffer) |
104 entries.append(resource); | 158 entries.append(resource); |
105 break; | 159 break; |
160 case PerformanceEntry::Navigation: | |
161 if (RuntimeEnabledFeatures::performanceNavigationTimingEnabled()) { | |
162 entries.append(m_navigationTiming); | |
163 } | |
kinuko
2016/11/06 15:16:43
nit: no { } for single-line body in blink
sunjian
2016/11/08 02:10:19
Done.
| |
164 break; | |
106 case PerformanceEntry::Composite: | 165 case PerformanceEntry::Composite: |
107 case PerformanceEntry::Render: | 166 case PerformanceEntry::Render: |
108 for (const auto& frame : m_frameTimingBuffer) { | 167 for (const auto& frame : m_frameTimingBuffer) { |
109 if (type == frame->entryTypeEnum()) { | 168 if (type == frame->entryTypeEnum()) { |
110 entries.append(frame); | 169 entries.append(frame); |
111 } | 170 } |
112 } | 171 } |
113 break; | 172 break; |
114 case PerformanceEntry::Mark: | 173 case PerformanceEntry::Mark: |
115 if (m_userTiming) | 174 if (m_userTiming) |
(...skipping 20 matching lines...) Expand all Loading... | |
136 if (!entryType.isNull() && type == PerformanceEntry::Invalid) | 195 if (!entryType.isNull() && type == PerformanceEntry::Invalid) |
137 return entries; | 196 return entries; |
138 | 197 |
139 if (entryType.isNull() || type == PerformanceEntry::Resource) { | 198 if (entryType.isNull() || type == PerformanceEntry::Resource) { |
140 for (const auto& resource : m_resourceTimingBuffer) { | 199 for (const auto& resource : m_resourceTimingBuffer) { |
141 if (resource->name() == name) | 200 if (resource->name() == name) |
142 entries.append(resource); | 201 entries.append(resource); |
143 } | 202 } |
144 } | 203 } |
145 | 204 |
205 if (entryType.isNull() || type == PerformanceEntry::Navigation) { | |
206 if (RuntimeEnabledFeatures::performanceNavigationTimingEnabled() && | |
207 m_navigationTiming->name() == name) | |
208 entries.append(m_navigationTiming); | |
209 } | |
210 | |
146 if (entryType.isNull() || type == PerformanceEntry::Composite || | 211 if (entryType.isNull() || type == PerformanceEntry::Composite || |
147 type == PerformanceEntry::Render) { | 212 type == PerformanceEntry::Render) { |
148 for (const auto& frame : m_frameTimingBuffer) { | 213 for (const auto& frame : m_frameTimingBuffer) { |
149 if (frame->name() == name && | 214 if (frame->name() == name && |
150 (entryType.isNull() || entryType == frame->entryType())) | 215 (entryType.isNull() || entryType == frame->entryType())) |
151 entries.append(frame); | 216 entries.append(frame); |
152 } | 217 } |
153 } | 218 } |
154 | 219 |
155 if (m_userTiming) { | 220 if (m_userTiming) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
285 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); | 350 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); |
286 | 351 |
287 PerformanceEntry* entry = PerformanceResourceTiming::create( | 352 PerformanceEntry* entry = PerformanceResourceTiming::create( |
288 info, timeOrigin(), startTime, lastRedirectEndTime, allowTimingDetails, | 353 info, timeOrigin(), startTime, lastRedirectEndTime, allowTimingDetails, |
289 allowRedirectDetails); | 354 allowRedirectDetails); |
290 notifyObserversOfEntry(*entry); | 355 notifyObserversOfEntry(*entry); |
291 if (!isResourceTimingBufferFull()) | 356 if (!isResourceTimingBufferFull()) |
292 addResourceTimingBuffer(*entry); | 357 addResourceTimingBuffer(*entry); |
293 } | 358 } |
294 | 359 |
360 void PerformanceBase::addNavigationTiming(LocalFrame* frame) { | |
361 if (!RuntimeEnabledFeatures::performanceNavigationTimingEnabled()) | |
362 return; | |
363 DCHECK(frame); | |
364 const DocumentLoader* docLoader = documentLoader(frame); | |
365 DCHECK(docLoader); | |
366 const DocumentLoadTiming* docLoadTiming = documentLoadTiming(frame); | |
367 const DocumentTiming* docTiming = documentTiming(frame); | |
368 DCHECK(docLoadTiming); | |
369 DCHECK(docTiming); | |
370 | |
371 ResourceResponse finalResponse = docLoader->response(); | |
372 | |
373 // TODO(sunjian) Right now NavigationType doesn't seem to have a Prerender | |
374 // type yet, need to look into this | |
375 AtomicString type = getNavigationType(frame); | |
376 | |
377 ResourceLoadTiming* resourceLoadTiming = finalResponse.resourceLoadTiming(); | |
378 double lastRedirectEndTime = docLoadTiming->redirectEnd(); | |
379 double finishTime = docLoadTiming->loadEventEnd(); | |
380 | |
381 // TODO(sunjian) Implement transfer size. | |
kinuko
2016/11/06 15:16:43
please link to a bug
sunjian
2016/11/08 02:10:19
Done.
| |
382 unsigned long long transferSize = 0; | |
383 unsigned long long encodedBodyLength = finalResponse.encodedBodyLength(); | |
384 unsigned long long decodedBodyLength = finalResponse.decodedBodyLength(); | |
385 bool didReuseConnection = finalResponse.connectionReused(); | |
386 | |
387 m_navigationTiming = PerformanceNavigationTiming::create( | |
388 timeOrigin(), docLoadTiming->unloadEventStart(), | |
389 docLoadTiming->unloadEventEnd(), docLoadTiming->loadEventStart(), | |
390 docLoadTiming->loadEventEnd(), docLoadTiming->redirectCount(), | |
391 docTiming->domInteractive(), docTiming->domContentLoadedEventStart(), | |
392 docTiming->domContentLoadedEventEnd(), docTiming->domComplete(), type, | |
393 docLoadTiming->redirectStart(), docLoadTiming->redirectEnd(), | |
394 docLoadTiming->fetchStart(), docLoadTiming->responseEnd(), | |
395 docLoadTiming->hasCrossOriginRedirect(), | |
396 docLoadTiming->hasSameOriginAsPreviousDocument(), resourceLoadTiming, | |
397 lastRedirectEndTime, finishTime, transferSize, encodedBodyLength, | |
398 decodedBodyLength, didReuseConnection); | |
399 notifyObserversOfEntry(*m_navigationTiming); | |
400 } | |
401 | |
295 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry& entry) { | 402 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry& entry) { |
296 m_resourceTimingBuffer.append(&entry); | 403 m_resourceTimingBuffer.append(&entry); |
297 | 404 |
298 if (isResourceTimingBufferFull()) { | 405 if (isResourceTimingBufferFull()) { |
299 dispatchEvent(Event::create(EventTypeNames::resourcetimingbufferfull)); | 406 dispatchEvent(Event::create(EventTypeNames::resourcetimingbufferfull)); |
300 dispatchEvent( | 407 dispatchEvent( |
301 Event::create(EventTypeNames::webkitresourcetimingbufferfull)); | 408 Event::create(EventTypeNames::webkitresourcetimingbufferfull)); |
302 } | 409 } |
303 } | 410 } |
304 | 411 |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
457 return monotonicTimeToDOMHighResTimeStamp(monotonicTime) * 1000; | 564 return monotonicTimeToDOMHighResTimeStamp(monotonicTime) * 1000; |
458 } | 565 } |
459 | 566 |
460 DOMHighResTimeStamp PerformanceBase::now() const { | 567 DOMHighResTimeStamp PerformanceBase::now() const { |
461 return monotonicTimeToDOMHighResTimeStamp(monotonicallyIncreasingTime()); | 568 return monotonicTimeToDOMHighResTimeStamp(monotonicallyIncreasingTime()); |
462 } | 569 } |
463 | 570 |
464 DEFINE_TRACE(PerformanceBase) { | 571 DEFINE_TRACE(PerformanceBase) { |
465 visitor->trace(m_frameTimingBuffer); | 572 visitor->trace(m_frameTimingBuffer); |
466 visitor->trace(m_resourceTimingBuffer); | 573 visitor->trace(m_resourceTimingBuffer); |
574 visitor->trace(m_navigationTiming); | |
467 visitor->trace(m_userTiming); | 575 visitor->trace(m_userTiming); |
468 visitor->trace(m_observers); | 576 visitor->trace(m_observers); |
469 visitor->trace(m_activeObservers); | 577 visitor->trace(m_activeObservers); |
470 visitor->trace(m_suspendedObservers); | 578 visitor->trace(m_suspendedObservers); |
471 EventTargetWithInlineData::trace(visitor); | 579 EventTargetWithInlineData::trace(visitor); |
472 } | 580 } |
473 | 581 |
474 } // namespace blink | 582 } // namespace blink |
OLD | NEW |