Chromium Code Reviews| 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 |
| 48 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>; | 55 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>; |
| 49 | 56 |
| 50 static const size_t defaultResourceTimingBufferSize = 150; | 57 static const size_t defaultResourceTimingBufferSize = 150; |
| 51 static const size_t defaultFrameTimingBufferSize = 150; | 58 static const size_t defaultFrameTimingBufferSize = 150; |
| 52 | 59 |
| 53 PerformanceBase::PerformanceBase(double timeOrigin) | 60 PerformanceBase::PerformanceBase(double timeOrigin) |
| 54 : m_frameTimingBufferSize(defaultFrameTimingBufferSize), | 61 : m_frameTimingBufferSize(defaultFrameTimingBufferSize), |
| 55 m_resourceTimingBufferSize(defaultResourceTimingBufferSize), | 62 m_resourceTimingBufferSize(defaultResourceTimingBufferSize), |
| 63 m_navigationTiming(nullptr), | |
| 56 m_userTiming(nullptr), | 64 m_userTiming(nullptr), |
| 57 m_timeOrigin(timeOrigin), | 65 m_timeOrigin(timeOrigin), |
| 58 m_observerFilterOptions(PerformanceEntry::Invalid), | 66 m_observerFilterOptions(PerformanceEntry::Invalid), |
| 59 m_deliverObservationsTimer( | 67 m_deliverObservationsTimer( |
| 60 this, | 68 this, |
| 61 &PerformanceBase::deliverObservationsTimerFired) {} | 69 &PerformanceBase::deliverObservationsTimerFired) {} |
| 62 | 70 |
| 63 PerformanceBase::~PerformanceBase() {} | 71 PerformanceBase::~PerformanceBase() {} |
| 64 | 72 |
| 65 const AtomicString& PerformanceBase::interfaceName() const { | 73 const AtomicString& PerformanceBase::interfaceName() const { |
| 66 return EventTargetNames::Performance; | 74 return EventTargetNames::Performance; |
| 67 } | 75 } |
| 68 | 76 |
| 69 PerformanceTiming* PerformanceBase::timing() const { | 77 PerformanceTiming* PerformanceBase::timing() const { |
| 70 return nullptr; | 78 return nullptr; |
| 71 } | 79 } |
| 72 | 80 |
| 73 PerformanceEntryVector PerformanceBase::getEntries() const { | 81 PerformanceEntryVector PerformanceBase::getEntries() const { |
| 74 PerformanceEntryVector entries; | 82 PerformanceEntryVector entries; |
| 75 | 83 |
| 76 entries.appendVector(m_resourceTimingBuffer); | 84 entries.appendVector(m_resourceTimingBuffer); |
| 85 if (RuntimeEnabledFeatures::performanceNavigationTiming2Enabled()) | |
| 86 entries.append(m_navigationTiming); | |
| 77 entries.appendVector(m_frameTimingBuffer); | 87 entries.appendVector(m_frameTimingBuffer); |
| 78 | 88 |
| 79 if (m_userTiming) { | 89 if (m_userTiming) { |
| 80 entries.appendVector(m_userTiming->getMarks()); | 90 entries.appendVector(m_userTiming->getMarks()); |
| 81 entries.appendVector(m_userTiming->getMeasures()); | 91 entries.appendVector(m_userTiming->getMeasures()); |
| 82 } | 92 } |
| 83 | 93 |
| 84 std::sort(entries.begin(), entries.end(), | 94 std::sort(entries.begin(), entries.end(), |
| 85 PerformanceEntry::startTimeCompareLessThan); | 95 PerformanceEntry::startTimeCompareLessThan); |
| 86 return entries; | 96 return entries; |
| 87 } | 97 } |
| 88 | 98 |
| 89 PerformanceEntryVector PerformanceBase::getEntriesByType( | 99 PerformanceEntryVector PerformanceBase::getEntriesByType( |
| 90 const String& entryType) { | 100 const String& entryType) { |
| 91 PerformanceEntryVector entries; | 101 PerformanceEntryVector entries; |
| 92 PerformanceEntry::EntryType type = | 102 PerformanceEntry::EntryType type = |
| 93 PerformanceEntry::toEntryTypeEnum(entryType); | 103 PerformanceEntry::toEntryTypeEnum(entryType); |
| 94 | 104 |
| 95 switch (type) { | 105 switch (type) { |
| 96 case PerformanceEntry::Invalid: | 106 case PerformanceEntry::Invalid: |
| 97 return entries; | 107 return entries; |
| 98 case PerformanceEntry::LongTask: | 108 case PerformanceEntry::LongTask: |
| 99 // Unsupported for LongTask. Per the spec, Long task entries can only be | 109 // Unsupported for LongTask. Per the spec, Long task entries can only be |
| 100 // accessed via Performance Observer. No separate buffer is maintained. | 110 // accessed via Performance Observer. No separate buffer is maintained. |
| 101 return entries; | 111 return entries; |
| 102 case PerformanceEntry::Resource: | 112 case PerformanceEntry::Resource: |
| 103 for (const auto& resource : m_resourceTimingBuffer) | 113 for (const auto& resource : m_resourceTimingBuffer) |
| 104 entries.append(resource); | 114 entries.append(resource); |
| 105 break; | 115 break; |
| 116 case PerformanceEntry::Navigation: | |
| 117 if (RuntimeEnabledFeatures::performanceNavigationTiming2Enabled()) | |
| 118 entries.append(m_navigationTiming); | |
| 119 break; | |
| 106 case PerformanceEntry::Composite: | 120 case PerformanceEntry::Composite: |
| 107 case PerformanceEntry::Render: | 121 case PerformanceEntry::Render: |
| 108 for (const auto& frame : m_frameTimingBuffer) { | 122 for (const auto& frame : m_frameTimingBuffer) { |
| 109 if (type == frame->entryTypeEnum()) { | 123 if (type == frame->entryTypeEnum()) { |
| 110 entries.append(frame); | 124 entries.append(frame); |
| 111 } | 125 } |
| 112 } | 126 } |
| 113 break; | 127 break; |
| 114 case PerformanceEntry::Mark: | 128 case PerformanceEntry::Mark: |
| 115 if (m_userTiming) | 129 if (m_userTiming) |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 136 if (!entryType.isNull() && type == PerformanceEntry::Invalid) | 150 if (!entryType.isNull() && type == PerformanceEntry::Invalid) |
| 137 return entries; | 151 return entries; |
| 138 | 152 |
| 139 if (entryType.isNull() || type == PerformanceEntry::Resource) { | 153 if (entryType.isNull() || type == PerformanceEntry::Resource) { |
| 140 for (const auto& resource : m_resourceTimingBuffer) { | 154 for (const auto& resource : m_resourceTimingBuffer) { |
| 141 if (resource->name() == name) | 155 if (resource->name() == name) |
| 142 entries.append(resource); | 156 entries.append(resource); |
| 143 } | 157 } |
| 144 } | 158 } |
| 145 | 159 |
| 160 if (entryType.isNull() || type == PerformanceEntry::Navigation) { | |
|
panicker
2016/11/08 18:27:06
these should be "else if" to avoid needless execut
sunjian
2016/11/08 23:16:21
I think they intended to collect all entries with
| |
| 161 if (RuntimeEnabledFeatures::performanceNavigationTiming2Enabled() && | |
| 162 m_navigationTiming->name() == name) | |
| 163 entries.append(m_navigationTiming); | |
| 164 } | |
| 165 | |
| 146 if (entryType.isNull() || type == PerformanceEntry::Composite || | 166 if (entryType.isNull() || type == PerformanceEntry::Composite || |
| 147 type == PerformanceEntry::Render) { | 167 type == PerformanceEntry::Render) { |
| 148 for (const auto& frame : m_frameTimingBuffer) { | 168 for (const auto& frame : m_frameTimingBuffer) { |
| 149 if (frame->name() == name && | 169 if (frame->name() == name && |
| 150 (entryType.isNull() || entryType == frame->entryType())) | 170 (entryType.isNull() || entryType == frame->entryType())) |
| 151 entries.append(frame); | 171 entries.append(frame); |
| 152 } | 172 } |
| 153 } | 173 } |
| 154 | 174 |
| 155 if (m_userTiming) { | 175 if (m_userTiming) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); | 305 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); |
| 286 | 306 |
| 287 PerformanceEntry* entry = PerformanceResourceTiming::create( | 307 PerformanceEntry* entry = PerformanceResourceTiming::create( |
| 288 info, timeOrigin(), startTime, lastRedirectEndTime, allowTimingDetails, | 308 info, timeOrigin(), startTime, lastRedirectEndTime, allowTimingDetails, |
| 289 allowRedirectDetails); | 309 allowRedirectDetails); |
| 290 notifyObserversOfEntry(*entry); | 310 notifyObserversOfEntry(*entry); |
| 291 if (!isResourceTimingBufferFull()) | 311 if (!isResourceTimingBufferFull()) |
| 292 addResourceTimingBuffer(*entry); | 312 addResourceTimingBuffer(*entry); |
| 293 } | 313 } |
| 294 | 314 |
| 315 void PerformanceBase::addNavigationTiming(LocalFrame* frame) { | |
| 316 if (!RuntimeEnabledFeatures::performanceNavigationTiming2Enabled()) | |
| 317 return; | |
| 318 DCHECK(frame); | |
| 319 const DocumentLoader* docLoader = frame->loader().documentLoader(); | |
| 320 DCHECK(docLoader); | |
| 321 const DocumentLoadTiming docLoadTiming = docLoader->timing(); | |
| 322 const DocumentTiming docTiming = frame->document()->timing(); | |
|
kinuko
2016/11/08 13:39:32
We don't usually abbreviate variable names in blin
sunjian
2016/11/08 23:16:21
Done.
| |
| 323 | |
| 324 ResourceResponse finalResponse = docLoader->response(); | |
| 325 | |
| 326 ResourceLoadTiming* resourceLoadTiming = finalResponse.resourceLoadTiming(); | |
| 327 double lastRedirectEndTime = docLoadTiming.redirectEnd(); | |
| 328 double finishTime = docLoadTiming.loadEventEnd(); | |
| 329 | |
| 330 // TODO(sunjian) Implement transfer size. crbug/663187 | |
| 331 unsigned long long transferSize = 0; | |
| 332 unsigned long long encodedBodyLength = finalResponse.encodedBodyLength(); | |
| 333 unsigned long long decodedBodyLength = finalResponse.decodedBodyLength(); | |
| 334 bool didReuseConnection = finalResponse.connectionReused(); | |
| 335 | |
| 336 m_navigationTiming = new PerformanceNavigationTiming( | |
| 337 timeOrigin(), docLoadTiming.unloadEventStart(), | |
| 338 docLoadTiming.unloadEventEnd(), docLoadTiming.loadEventStart(), | |
| 339 docLoadTiming.loadEventEnd(), docLoadTiming.redirectCount(), | |
| 340 docTiming.domInteractive(), docTiming.domContentLoadedEventStart(), | |
| 341 docTiming.domContentLoadedEventEnd(), docTiming.domComplete(), | |
| 342 docLoader->getNavigationType(), docLoadTiming.redirectStart(), | |
| 343 docLoadTiming.redirectEnd(), docLoadTiming.fetchStart(), | |
| 344 docLoadTiming.responseEnd(), docLoadTiming.hasCrossOriginRedirect(), | |
| 345 docLoadTiming.hasSameOriginAsPreviousDocument(), resourceLoadTiming, | |
| 346 lastRedirectEndTime, finishTime, transferSize, encodedBodyLength, | |
| 347 decodedBodyLength, didReuseConnection); | |
| 348 notifyObserversOfEntry(*m_navigationTiming); | |
| 349 } | |
| 350 | |
| 295 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry& entry) { | 351 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry& entry) { |
| 296 m_resourceTimingBuffer.append(&entry); | 352 m_resourceTimingBuffer.append(&entry); |
| 297 | 353 |
| 298 if (isResourceTimingBufferFull()) { | 354 if (isResourceTimingBufferFull()) { |
| 299 dispatchEvent(Event::create(EventTypeNames::resourcetimingbufferfull)); | 355 dispatchEvent(Event::create(EventTypeNames::resourcetimingbufferfull)); |
| 300 dispatchEvent( | 356 dispatchEvent( |
| 301 Event::create(EventTypeNames::webkitresourcetimingbufferfull)); | 357 Event::create(EventTypeNames::webkitresourcetimingbufferfull)); |
| 302 } | 358 } |
| 303 } | 359 } |
| 304 | 360 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 return monotonicTimeToDOMHighResTimeStamp(monotonicTime) * 1000; | 513 return monotonicTimeToDOMHighResTimeStamp(monotonicTime) * 1000; |
| 458 } | 514 } |
| 459 | 515 |
| 460 DOMHighResTimeStamp PerformanceBase::now() const { | 516 DOMHighResTimeStamp PerformanceBase::now() const { |
| 461 return monotonicTimeToDOMHighResTimeStamp(monotonicallyIncreasingTime()); | 517 return monotonicTimeToDOMHighResTimeStamp(monotonicallyIncreasingTime()); |
| 462 } | 518 } |
| 463 | 519 |
| 464 DEFINE_TRACE(PerformanceBase) { | 520 DEFINE_TRACE(PerformanceBase) { |
| 465 visitor->trace(m_frameTimingBuffer); | 521 visitor->trace(m_frameTimingBuffer); |
| 466 visitor->trace(m_resourceTimingBuffer); | 522 visitor->trace(m_resourceTimingBuffer); |
| 523 visitor->trace(m_navigationTiming); | |
| 467 visitor->trace(m_userTiming); | 524 visitor->trace(m_userTiming); |
| 468 visitor->trace(m_observers); | 525 visitor->trace(m_observers); |
| 469 visitor->trace(m_activeObservers); | 526 visitor->trace(m_activeObservers); |
| 470 visitor->trace(m_suspendedObservers); | 527 visitor->trace(m_suspendedObservers); |
| 471 EventTargetWithInlineData::trace(visitor); | 528 EventTargetWithInlineData::trace(visitor); |
| 472 } | 529 } |
| 473 | 530 |
| 474 } // namespace blink | 531 } // namespace blink |
| OLD | NEW |