| 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 24 matching lines...) Expand all Loading... |
| 35 #include "core/dom/Document.h" | 35 #include "core/dom/Document.h" |
| 36 #include "core/dom/DocumentTiming.h" | 36 #include "core/dom/DocumentTiming.h" |
| 37 #include "core/events/Event.h" | 37 #include "core/events/Event.h" |
| 38 #include "core/frame/LocalFrame.h" | 38 #include "core/frame/LocalFrame.h" |
| 39 #include "core/frame/UseCounter.h" | 39 #include "core/frame/UseCounter.h" |
| 40 #include "core/loader/DocumentLoadTiming.h" | 40 #include "core/loader/DocumentLoadTiming.h" |
| 41 #include "core/loader/DocumentLoader.h" | 41 #include "core/loader/DocumentLoader.h" |
| 42 #include "core/timing/PerformanceLongTaskTiming.h" | 42 #include "core/timing/PerformanceLongTaskTiming.h" |
| 43 #include "core/timing/PerformanceObserver.h" | 43 #include "core/timing/PerformanceObserver.h" |
| 44 #include "core/timing/PerformanceResourceTiming.h" | 44 #include "core/timing/PerformanceResourceTiming.h" |
| 45 #include "core/timing/PerformanceServerTiming.h" |
| 45 #include "core/timing/PerformanceUserTiming.h" | 46 #include "core/timing/PerformanceUserTiming.h" |
| 46 #include "platform/RuntimeEnabledFeatures.h" | 47 #include "platform/RuntimeEnabledFeatures.h" |
| 47 #include "platform/loader/fetch/ResourceResponse.h" | 48 #include "platform/loader/fetch/ResourceResponse.h" |
| 48 #include "platform/loader/fetch/ResourceTimingInfo.h" | 49 #include "platform/loader/fetch/ResourceTimingInfo.h" |
| 49 #include "platform/weborigin/SecurityOrigin.h" | 50 #include "platform/weborigin/SecurityOrigin.h" |
| 50 #include "platform/wtf/CurrentTime.h" | 51 #include "platform/wtf/CurrentTime.h" |
| 51 | 52 |
| 52 namespace blink { | 53 namespace blink { |
| 53 | 54 |
| 54 namespace { | 55 namespace { |
| 55 | 56 |
| 56 SecurityOrigin* GetSecurityOrigin(ExecutionContext* context) { | 57 SecurityOrigin* GetSecurityOrigin(ExecutionContext* context) { |
| 57 if (context) | 58 if (context) |
| 58 return context->GetSecurityOrigin(); | 59 return context->GetSecurityOrigin(); |
| 59 return nullptr; | 60 return nullptr; |
| 60 } | 61 } |
| 61 | 62 |
| 62 } // namespace | 63 } // namespace |
| 63 | 64 |
| 64 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>; | 65 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>; |
| 65 | 66 |
| 66 static const size_t kDefaultResourceTimingBufferSize = 150; | 67 static const size_t kDefaultResourceTimingBufferSize = 150; |
| 67 static const size_t kDefaultFrameTimingBufferSize = 150; | 68 static const size_t kDefaultFrameTimingBufferSize = 150; |
| 69 static const size_t kServerTimingBufferSize = 150; |
| 68 | 70 |
| 69 PerformanceBase::PerformanceBase(double time_origin, | 71 PerformanceBase::PerformanceBase(double time_origin, |
| 70 RefPtr<WebTaskRunner> task_runner) | 72 RefPtr<WebTaskRunner> task_runner) |
| 71 : frame_timing_buffer_size_(kDefaultFrameTimingBufferSize), | 73 : frame_timing_buffer_size_(kDefaultFrameTimingBufferSize), |
| 72 resource_timing_buffer_size_(kDefaultResourceTimingBufferSize), | 74 resource_timing_buffer_size_(kDefaultResourceTimingBufferSize), |
| 73 user_timing_(nullptr), | 75 user_timing_(nullptr), |
| 74 time_origin_(time_origin), | 76 time_origin_(time_origin), |
| 75 observer_filter_options_(PerformanceEntry::kInvalid), | 77 observer_filter_options_(PerformanceEntry::kInvalid), |
| 76 deliver_observations_timer_( | 78 deliver_observations_timer_( |
| 77 std::move(task_runner), | 79 std::move(task_runner), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 98 // calls this method. | 100 // calls this method. |
| 99 if (navigation_timing_) | 101 if (navigation_timing_) |
| 100 entries.push_back(navigation_timing_); | 102 entries.push_back(navigation_timing_); |
| 101 entries.AppendVector(frame_timing_buffer_); | 103 entries.AppendVector(frame_timing_buffer_); |
| 102 | 104 |
| 103 if (user_timing_) { | 105 if (user_timing_) { |
| 104 entries.AppendVector(user_timing_->GetMarks()); | 106 entries.AppendVector(user_timing_->GetMarks()); |
| 105 entries.AppendVector(user_timing_->GetMeasures()); | 107 entries.AppendVector(user_timing_->GetMeasures()); |
| 106 } | 108 } |
| 107 | 109 |
| 110 entries.AppendVector(server_timing_buffer_); |
| 111 |
| 108 std::sort(entries.begin(), entries.end(), | 112 std::sort(entries.begin(), entries.end(), |
| 109 PerformanceEntry::StartTimeCompareLessThan); | 113 PerformanceEntry::StartTimeCompareLessThan); |
| 110 return entries; | 114 return entries; |
| 111 } | 115 } |
| 112 | 116 |
| 113 PerformanceEntryVector PerformanceBase::getEntriesByType( | 117 PerformanceEntryVector PerformanceBase::getEntriesByType( |
| 114 const String& entry_type) { | 118 const String& entry_type) { |
| 115 PerformanceEntryVector entries; | 119 PerformanceEntryVector entries; |
| 116 PerformanceEntry::EntryType type = | 120 PerformanceEntry::EntryType type = |
| 117 PerformanceEntry::ToEntryTypeEnum(entry_type); | 121 PerformanceEntry::ToEntryTypeEnum(entry_type); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 136 } | 140 } |
| 137 break; | 141 break; |
| 138 case PerformanceEntry::kMark: | 142 case PerformanceEntry::kMark: |
| 139 if (user_timing_) | 143 if (user_timing_) |
| 140 entries.AppendVector(user_timing_->GetMarks()); | 144 entries.AppendVector(user_timing_->GetMarks()); |
| 141 break; | 145 break; |
| 142 case PerformanceEntry::kMeasure: | 146 case PerformanceEntry::kMeasure: |
| 143 if (user_timing_) | 147 if (user_timing_) |
| 144 entries.AppendVector(user_timing_->GetMeasures()); | 148 entries.AppendVector(user_timing_->GetMeasures()); |
| 145 break; | 149 break; |
| 150 case PerformanceEntry::kServer: |
| 151 entries.AppendVector(server_timing_buffer_); |
| 152 break; |
| 146 // Unsupported for Paint, LongTask, TaskAttribution. | 153 // Unsupported for Paint, LongTask, TaskAttribution. |
| 147 // Per the spec, these entries can only be accessed via | 154 // Per the spec, these entries can only be accessed via |
| 148 // Performance Observer. No separate buffer is maintained. | 155 // Performance Observer. No separate buffer is maintained. |
| 149 case PerformanceEntry::kPaint: | 156 case PerformanceEntry::kPaint: |
| 150 break; | 157 break; |
| 151 case PerformanceEntry::kLongTask: | 158 case PerformanceEntry::kLongTask: |
| 152 break; | 159 break; |
| 153 case PerformanceEntry::kTaskAttribution: | 160 case PerformanceEntry::kTaskAttribution: |
| 154 break; | 161 break; |
| 155 case PerformanceEntry::kInvalid: | 162 case PerformanceEntry::kInvalid: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 } | 201 } |
| 195 } | 202 } |
| 196 | 203 |
| 197 if (user_timing_) { | 204 if (user_timing_) { |
| 198 if (entry_type.IsNull() || type == PerformanceEntry::kMark) | 205 if (entry_type.IsNull() || type == PerformanceEntry::kMark) |
| 199 entries.AppendVector(user_timing_->GetMarks(name)); | 206 entries.AppendVector(user_timing_->GetMarks(name)); |
| 200 if (entry_type.IsNull() || type == PerformanceEntry::kMeasure) | 207 if (entry_type.IsNull() || type == PerformanceEntry::kMeasure) |
| 201 entries.AppendVector(user_timing_->GetMeasures(name)); | 208 entries.AppendVector(user_timing_->GetMeasures(name)); |
| 202 } | 209 } |
| 203 | 210 |
| 211 if (entry_type.IsNull() || type == PerformanceEntry::kServer) { |
| 212 // This is inefficient, but this buffer has a max size of |
| 213 // 150 entries (controlled by kServerTimingBufferSize). |
| 214 for (const auto& entry : server_timing_buffer_) { |
| 215 if (entry->name() == name) |
| 216 entries.push_back(entry); |
| 217 } |
| 218 } |
| 219 |
| 204 std::sort(entries.begin(), entries.end(), | 220 std::sort(entries.begin(), entries.end(), |
| 205 PerformanceEntry::StartTimeCompareLessThan); | 221 PerformanceEntry::StartTimeCompareLessThan); |
| 206 return entries; | 222 return entries; |
| 207 } | 223 } |
| 208 | 224 |
| 209 void PerformanceBase::clearResourceTimings() { | 225 void PerformanceBase::clearResourceTimings() { |
| 210 resource_timing_buffer_.clear(); | 226 resource_timing_buffer_.clear(); |
| 211 } | 227 } |
| 212 | 228 |
| 213 void PerformanceBase::setResourceTimingBufferSize(unsigned size) { | 229 void PerformanceBase::setResourceTimingBufferSize(unsigned size) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 | 291 |
| 276 for (const ResourceResponse& response : redirect_chain) { | 292 for (const ResourceResponse& response : redirect_chain) { |
| 277 if (!PassesTimingAllowCheck(response, initiator_security_origin, | 293 if (!PassesTimingAllowCheck(response, initiator_security_origin, |
| 278 AtomicString(), context)) | 294 AtomicString(), context)) |
| 279 return false; | 295 return false; |
| 280 } | 296 } |
| 281 | 297 |
| 282 return true; | 298 return true; |
| 283 } | 299 } |
| 284 | 300 |
| 301 void PerformanceBase::AddServerTiming(const ResourceResponse& response, |
| 302 ShouldAddToBuffer shouldAddToBuffer) { |
| 303 if (shouldAddToBuffer == ShouldAddToBuffer::Never && |
| 304 !HasObserverFor(PerformanceEntry::kServer)) { |
| 305 return; |
| 306 } |
| 307 |
| 308 ExecutionContext* context = GetExecutionContext(); |
| 309 SecurityOrigin* securityOrigin = GetSecurityOrigin(context); |
| 310 if (!securityOrigin) { |
| 311 return; |
| 312 } |
| 313 bool allowTimingDetails = PassesTimingAllowCheck( |
| 314 response, *securityOrigin, |
| 315 response.HttpHeaderField(HTTPNames::Timing_Allow_Origin), context); |
| 316 |
| 317 std::unique_ptr<ServerTimingHeaderVector> headers = ParseServerTimingHeader( |
| 318 response.HttpHeaderField(HTTPNames::Server_Timing)); |
| 319 if ((*headers).size() == 0) { |
| 320 return; |
| 321 } |
| 322 |
| 323 PerformanceEntryVector entries; |
| 324 for (const auto& header : *headers) { |
| 325 PerformanceEntry* entry = PerformanceServerTiming::create( |
| 326 response.Url().GetString(), header->metric, |
| 327 allowTimingDetails ? header->duration : 0.0, |
| 328 allowTimingDetails ? header->description : ""); |
| 329 entries.push_back(*entry); |
| 330 } |
| 331 |
| 332 NotifyObserversOfEntries(entries); |
| 333 if (shouldAddToBuffer == ShouldAddToBuffer::Always && |
| 334 server_timing_buffer_.size() + entries.size() <= |
| 335 kServerTimingBufferSize) { |
| 336 server_timing_buffer_.AppendVector(entries); |
| 337 } |
| 338 } |
| 339 |
| 285 void PerformanceBase::AddResourceTiming(const ResourceTimingInfo& info) { | 340 void PerformanceBase::AddResourceTiming(const ResourceTimingInfo& info) { |
| 286 if (IsResourceTimingBufferFull() && | 341 if (IsResourceTimingBufferFull() && |
| 287 !HasObserverFor(PerformanceEntry::kResource)) | 342 !HasObserverFor(PerformanceEntry::kResource)) |
| 288 return; | 343 return; |
| 289 ExecutionContext* context = GetExecutionContext(); | 344 ExecutionContext* context = GetExecutionContext(); |
| 290 SecurityOrigin* security_origin = GetSecurityOrigin(context); | 345 SecurityOrigin* security_origin = GetSecurityOrigin(context); |
| 291 if (!security_origin) | 346 if (!security_origin) |
| 292 return; | 347 return; |
| 293 | 348 |
| 294 const ResourceResponse& final_response = info.FinalResponse(); | 349 const ResourceResponse& final_response = info.FinalResponse(); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 UpdateLongTaskInstrumentation(); | 508 UpdateLongTaskInstrumentation(); |
| 454 } | 509 } |
| 455 | 510 |
| 456 void PerformanceBase::NotifyObserversOfEntry(PerformanceEntry& entry) { | 511 void PerformanceBase::NotifyObserversOfEntry(PerformanceEntry& entry) { |
| 457 for (auto& observer : observers_) { | 512 for (auto& observer : observers_) { |
| 458 if (observer->FilterOptions() & entry.EntryTypeEnum()) | 513 if (observer->FilterOptions() & entry.EntryTypeEnum()) |
| 459 observer->EnqueuePerformanceEntry(entry); | 514 observer->EnqueuePerformanceEntry(entry); |
| 460 } | 515 } |
| 461 } | 516 } |
| 462 | 517 |
| 518 void PerformanceBase::NotifyObserversOfEntries( |
| 519 PerformanceEntryVector& entries) { |
| 520 for (const auto& entry : entries) { |
| 521 NotifyObserversOfEntry(*entry.Get()); |
| 522 } |
| 523 } |
| 524 |
| 463 bool PerformanceBase::HasObserverFor( | 525 bool PerformanceBase::HasObserverFor( |
| 464 PerformanceEntry::EntryType filter_type) const { | 526 PerformanceEntry::EntryType filter_type) const { |
| 465 return observer_filter_options_ & filter_type; | 527 return observer_filter_options_ & filter_type; |
| 466 } | 528 } |
| 467 | 529 |
| 468 void PerformanceBase::ActivateObserver(PerformanceObserver& observer) { | 530 void PerformanceBase::ActivateObserver(PerformanceObserver& observer) { |
| 469 if (active_observers_.IsEmpty()) | 531 if (active_observers_.IsEmpty()) |
| 470 deliver_observations_timer_.StartOneShot(0, BLINK_FROM_HERE); | 532 deliver_observations_timer_.StartOneShot(0, BLINK_FROM_HERE); |
| 471 | 533 |
| 472 active_observers_.insert(&observer); | 534 active_observers_.insert(&observer); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 | 588 |
| 527 DOMHighResTimeStamp PerformanceBase::now() const { | 589 DOMHighResTimeStamp PerformanceBase::now() const { |
| 528 return MonotonicTimeToDOMHighResTimeStamp(MonotonicallyIncreasingTime()); | 590 return MonotonicTimeToDOMHighResTimeStamp(MonotonicallyIncreasingTime()); |
| 529 } | 591 } |
| 530 | 592 |
| 531 DEFINE_TRACE(PerformanceBase) { | 593 DEFINE_TRACE(PerformanceBase) { |
| 532 visitor->Trace(frame_timing_buffer_); | 594 visitor->Trace(frame_timing_buffer_); |
| 533 visitor->Trace(resource_timing_buffer_); | 595 visitor->Trace(resource_timing_buffer_); |
| 534 visitor->Trace(navigation_timing_); | 596 visitor->Trace(navigation_timing_); |
| 535 visitor->Trace(user_timing_); | 597 visitor->Trace(user_timing_); |
| 598 visitor->Trace(server_timing_buffer_); |
| 536 visitor->Trace(observers_); | 599 visitor->Trace(observers_); |
| 537 visitor->Trace(active_observers_); | 600 visitor->Trace(active_observers_); |
| 538 visitor->Trace(suspended_observers_); | 601 visitor->Trace(suspended_observers_); |
| 539 EventTargetWithInlineData::Trace(visitor); | 602 EventTargetWithInlineData::Trace(visitor); |
| 540 } | 603 } |
| 541 | 604 |
| 542 } // namespace blink | 605 } // namespace blink |
| OLD | NEW |