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" |
35 #include "core/events/Event.h" | 36 #include "core/events/Event.h" |
| 37 #include "core/frame/LocalFrame.h" |
36 #include "core/frame/UseCounter.h" | 38 #include "core/frame/UseCounter.h" |
| 39 #include "core/loader/DocumentLoadTiming.h" |
| 40 #include "core/loader/DocumentLoader.h" |
37 #include "core/timing/PerformanceLongTaskTiming.h" | 41 #include "core/timing/PerformanceLongTaskTiming.h" |
| 42 #include "core/timing/PerformanceNavigationTiming.h" |
38 #include "core/timing/PerformanceObserver.h" | 43 #include "core/timing/PerformanceObserver.h" |
39 #include "core/timing/PerformanceResourceTiming.h" | 44 #include "core/timing/PerformanceResourceTiming.h" |
40 #include "core/timing/PerformanceUserTiming.h" | 45 #include "core/timing/PerformanceUserTiming.h" |
| 46 #include "platform/RuntimeEnabledFeatures.h" |
41 #include "platform/network/ResourceTimingInfo.h" | 47 #include "platform/network/ResourceTimingInfo.h" |
42 #include "platform/weborigin/SecurityOrigin.h" | 48 #include "platform/weborigin/SecurityOrigin.h" |
43 #include "wtf/CurrentTime.h" | 49 #include "wtf/CurrentTime.h" |
44 #include <algorithm> | 50 #include <algorithm> |
45 | 51 |
46 namespace blink { | 52 namespace blink { |
47 | 53 |
48 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>; | 54 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>; |
49 | 55 |
50 static const size_t defaultResourceTimingBufferSize = 150; | 56 static const size_t defaultResourceTimingBufferSize = 150; |
(...skipping 16 matching lines...) Expand all Loading... |
67 } | 73 } |
68 | 74 |
69 PerformanceTiming* PerformanceBase::timing() const { | 75 PerformanceTiming* PerformanceBase::timing() const { |
70 return nullptr; | 76 return nullptr; |
71 } | 77 } |
72 | 78 |
73 PerformanceEntryVector PerformanceBase::getEntries() const { | 79 PerformanceEntryVector PerformanceBase::getEntries() const { |
74 PerformanceEntryVector entries; | 80 PerformanceEntryVector entries; |
75 | 81 |
76 entries.appendVector(m_resourceTimingBuffer); | 82 entries.appendVector(m_resourceTimingBuffer); |
| 83 if (m_navigationTiming) |
| 84 entries.append(m_navigationTiming); |
77 entries.appendVector(m_frameTimingBuffer); | 85 entries.appendVector(m_frameTimingBuffer); |
78 | 86 |
79 if (m_userTiming) { | 87 if (m_userTiming) { |
80 entries.appendVector(m_userTiming->getMarks()); | 88 entries.appendVector(m_userTiming->getMarks()); |
81 entries.appendVector(m_userTiming->getMeasures()); | 89 entries.appendVector(m_userTiming->getMeasures()); |
82 } | 90 } |
83 | 91 |
84 std::sort(entries.begin(), entries.end(), | 92 std::sort(entries.begin(), entries.end(), |
85 PerformanceEntry::startTimeCompareLessThan); | 93 PerformanceEntry::startTimeCompareLessThan); |
86 return entries; | 94 return entries; |
87 } | 95 } |
88 | 96 |
89 PerformanceEntryVector PerformanceBase::getEntriesByType( | 97 PerformanceEntryVector PerformanceBase::getEntriesByType( |
90 const String& entryType) { | 98 const String& entryType) { |
91 PerformanceEntryVector entries; | 99 PerformanceEntryVector entries; |
92 PerformanceEntry::EntryType type = | 100 PerformanceEntry::EntryType type = |
93 PerformanceEntry::toEntryTypeEnum(entryType); | 101 PerformanceEntry::toEntryTypeEnum(entryType); |
94 | 102 |
95 switch (type) { | 103 switch (type) { |
96 case PerformanceEntry::Invalid: | 104 case PerformanceEntry::Invalid: |
97 return entries; | 105 return entries; |
98 case PerformanceEntry::LongTask: | 106 case PerformanceEntry::LongTask: |
99 // Unsupported for LongTask. Per the spec, Long task entries can only be | 107 // Unsupported for LongTask. Per the spec, Long task entries can only be |
100 // accessed via Performance Observer. No separate buffer is maintained. | 108 // accessed via Performance Observer. No separate buffer is maintained. |
101 return entries; | 109 return entries; |
102 case PerformanceEntry::Resource: | 110 case PerformanceEntry::Resource: |
103 for (const auto& resource : m_resourceTimingBuffer) | 111 for (const auto& resource : m_resourceTimingBuffer) |
104 entries.append(resource); | 112 entries.append(resource); |
105 break; | 113 break; |
| 114 case PerformanceEntry::Navigation: |
| 115 if (m_navigationTiming) |
| 116 entries.append(m_navigationTiming); |
| 117 break; |
106 case PerformanceEntry::Composite: | 118 case PerformanceEntry::Composite: |
107 case PerformanceEntry::Render: | 119 case PerformanceEntry::Render: |
108 for (const auto& frame : m_frameTimingBuffer) { | 120 for (const auto& frame : m_frameTimingBuffer) { |
109 if (type == frame->entryTypeEnum()) { | 121 if (type == frame->entryTypeEnum()) { |
110 entries.append(frame); | 122 entries.append(frame); |
111 } | 123 } |
112 } | 124 } |
113 break; | 125 break; |
114 case PerformanceEntry::Mark: | 126 case PerformanceEntry::Mark: |
115 if (m_userTiming) | 127 if (m_userTiming) |
(...skipping 20 matching lines...) Expand all Loading... |
136 if (!entryType.isNull() && type == PerformanceEntry::Invalid) | 148 if (!entryType.isNull() && type == PerformanceEntry::Invalid) |
137 return entries; | 149 return entries; |
138 | 150 |
139 if (entryType.isNull() || type == PerformanceEntry::Resource) { | 151 if (entryType.isNull() || type == PerformanceEntry::Resource) { |
140 for (const auto& resource : m_resourceTimingBuffer) { | 152 for (const auto& resource : m_resourceTimingBuffer) { |
141 if (resource->name() == name) | 153 if (resource->name() == name) |
142 entries.append(resource); | 154 entries.append(resource); |
143 } | 155 } |
144 } | 156 } |
145 | 157 |
| 158 if (entryType.isNull() || type == PerformanceEntry::Navigation) { |
| 159 if (m_navigationTiming && m_navigationTiming->name() == name) |
| 160 entries.append(m_navigationTiming); |
| 161 } |
| 162 |
146 if (entryType.isNull() || type == PerformanceEntry::Composite || | 163 if (entryType.isNull() || type == PerformanceEntry::Composite || |
147 type == PerformanceEntry::Render) { | 164 type == PerformanceEntry::Render) { |
148 for (const auto& frame : m_frameTimingBuffer) { | 165 for (const auto& frame : m_frameTimingBuffer) { |
149 if (frame->name() == name && | 166 if (frame->name() == name && |
150 (entryType.isNull() || entryType == frame->entryType())) | 167 (entryType.isNull() || entryType == frame->entryType())) |
151 entries.append(frame); | 168 entries.append(frame); |
152 } | 169 } |
153 } | 170 } |
154 | 171 |
155 if (m_userTiming) { | 172 if (m_userTiming) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); | 302 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); |
286 | 303 |
287 PerformanceEntry* entry = PerformanceResourceTiming::create( | 304 PerformanceEntry* entry = PerformanceResourceTiming::create( |
288 info, timeOrigin(), startTime, lastRedirectEndTime, allowTimingDetails, | 305 info, timeOrigin(), startTime, lastRedirectEndTime, allowTimingDetails, |
289 allowRedirectDetails); | 306 allowRedirectDetails); |
290 notifyObserversOfEntry(*entry); | 307 notifyObserversOfEntry(*entry); |
291 if (!isResourceTimingBufferFull()) | 308 if (!isResourceTimingBufferFull()) |
292 addResourceTimingBuffer(*entry); | 309 addResourceTimingBuffer(*entry); |
293 } | 310 } |
294 | 311 |
| 312 void PerformanceBase::addNavigationTiming(LocalFrame* frame) { |
| 313 if (!RuntimeEnabledFeatures::performanceNavigationTiming2Enabled()) |
| 314 return; |
| 315 DCHECK(frame); |
| 316 const DocumentLoader* documentLoader = frame->loader().documentLoader(); |
| 317 DCHECK(documentLoader); |
| 318 const DocumentLoadTiming& documentLoadTiming = documentLoader->timing(); |
| 319 |
| 320 const DocumentTiming* documentTiming = |
| 321 frame->document() ? &(frame->document()->timing()) : nullptr; |
| 322 |
| 323 const ResourceResponse& finalResponse = documentLoader->response(); |
| 324 |
| 325 ResourceLoadTiming* resourceLoadTiming = finalResponse.resourceLoadTiming(); |
| 326 // Don't create a navigation timing instance when |
| 327 // resourceLoadTiming is null, which could happen when visiting non-http sites |
| 328 // such as about:blank or in some error cases. |
| 329 if (!resourceLoadTiming) |
| 330 return; |
| 331 double lastRedirectEndTime = documentLoadTiming.redirectEnd(); |
| 332 double finishTime = documentLoadTiming.loadEventEnd(); |
| 333 |
| 334 // TODO(sunjian) Implement transfer size. crbug/663187 |
| 335 unsigned long long transferSize = 0; |
| 336 unsigned long long encodedBodyLength = finalResponse.encodedBodyLength(); |
| 337 unsigned long long decodedBodyLength = finalResponse.decodedBodyLength(); |
| 338 bool didReuseConnection = finalResponse.connectionReused(); |
| 339 |
| 340 m_navigationTiming = new PerformanceNavigationTiming( |
| 341 timeOrigin(), documentLoadTiming.unloadEventStart(), |
| 342 documentLoadTiming.unloadEventEnd(), documentLoadTiming.loadEventStart(), |
| 343 documentLoadTiming.loadEventEnd(), documentLoadTiming.redirectCount(), |
| 344 documentTiming ? documentTiming->domInteractive() : 0, |
| 345 documentTiming ? documentTiming->domContentLoadedEventStart() : 0, |
| 346 documentTiming ? documentTiming->domContentLoadedEventEnd() : 0, |
| 347 documentTiming ? documentTiming->domComplete() : 0, |
| 348 documentLoader->getNavigationType(), documentLoadTiming.redirectStart(), |
| 349 documentLoadTiming.redirectEnd(), documentLoadTiming.fetchStart(), |
| 350 documentLoadTiming.responseEnd(), |
| 351 documentLoadTiming.hasCrossOriginRedirect(), |
| 352 documentLoadTiming.hasSameOriginAsPreviousDocument(), resourceLoadTiming, |
| 353 lastRedirectEndTime, finishTime, transferSize, encodedBodyLength, |
| 354 decodedBodyLength, didReuseConnection); |
| 355 notifyObserversOfEntry(*m_navigationTiming); |
| 356 } |
| 357 |
295 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry& entry) { | 358 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry& entry) { |
296 m_resourceTimingBuffer.append(&entry); | 359 m_resourceTimingBuffer.append(&entry); |
297 | 360 |
298 if (isResourceTimingBufferFull()) { | 361 if (isResourceTimingBufferFull()) { |
299 dispatchEvent(Event::create(EventTypeNames::resourcetimingbufferfull)); | 362 dispatchEvent(Event::create(EventTypeNames::resourcetimingbufferfull)); |
300 dispatchEvent( | 363 dispatchEvent( |
301 Event::create(EventTypeNames::webkitresourcetimingbufferfull)); | 364 Event::create(EventTypeNames::webkitresourcetimingbufferfull)); |
302 } | 365 } |
303 } | 366 } |
304 | 367 |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 return monotonicTimeToDOMHighResTimeStamp(monotonicTime) * 1000; | 520 return monotonicTimeToDOMHighResTimeStamp(monotonicTime) * 1000; |
458 } | 521 } |
459 | 522 |
460 DOMHighResTimeStamp PerformanceBase::now() const { | 523 DOMHighResTimeStamp PerformanceBase::now() const { |
461 return monotonicTimeToDOMHighResTimeStamp(monotonicallyIncreasingTime()); | 524 return monotonicTimeToDOMHighResTimeStamp(monotonicallyIncreasingTime()); |
462 } | 525 } |
463 | 526 |
464 DEFINE_TRACE(PerformanceBase) { | 527 DEFINE_TRACE(PerformanceBase) { |
465 visitor->trace(m_frameTimingBuffer); | 528 visitor->trace(m_frameTimingBuffer); |
466 visitor->trace(m_resourceTimingBuffer); | 529 visitor->trace(m_resourceTimingBuffer); |
| 530 visitor->trace(m_navigationTiming); |
467 visitor->trace(m_userTiming); | 531 visitor->trace(m_userTiming); |
468 visitor->trace(m_observers); | 532 visitor->trace(m_observers); |
469 visitor->trace(m_activeObservers); | 533 visitor->trace(m_activeObservers); |
470 visitor->trace(m_suspendedObservers); | 534 visitor->trace(m_suspendedObservers); |
471 EventTargetWithInlineData::trace(visitor); | 535 EventTargetWithInlineData::trace(visitor); |
472 } | 536 } |
473 | 537 |
474 } // namespace blink | 538 } // namespace blink |
OLD | NEW |