Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(232)

Side by Side Diff: third_party/WebKit/Source/core/timing/PerformanceBase.cpp

Issue 2962113002: Updates to Server-Timing in accordance with with spec changes (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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"
46 #include "core/timing/PerformanceUserTiming.h" 45 #include "core/timing/PerformanceUserTiming.h"
47 #include "platform/RuntimeEnabledFeatures.h" 46 #include "platform/RuntimeEnabledFeatures.h"
48 #include "platform/loader/fetch/ResourceResponse.h" 47 #include "platform/loader/fetch/ResourceResponse.h"
49 #include "platform/loader/fetch/ResourceTimingInfo.h" 48 #include "platform/loader/fetch/ResourceTimingInfo.h"
50 #include "platform/weborigin/SecurityOrigin.h" 49 #include "platform/weborigin/SecurityOrigin.h"
51 #include "platform/wtf/CurrentTime.h" 50 #include "platform/wtf/CurrentTime.h"
52 51
53 namespace blink { 52 namespace blink {
54 53
55 namespace { 54 namespace {
56 55
57 SecurityOrigin* GetSecurityOrigin(ExecutionContext* context) { 56 SecurityOrigin* GetSecurityOrigin(ExecutionContext* context) {
58 if (context) 57 if (context)
59 return context->GetSecurityOrigin(); 58 return context->GetSecurityOrigin();
60 return nullptr; 59 return nullptr;
61 } 60 }
62 61
63 } // namespace 62 } // namespace
64 63
65 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>; 64 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>;
66 65
67 static const size_t kDefaultResourceTimingBufferSize = 150; 66 static const size_t kDefaultResourceTimingBufferSize = 150;
68 static const size_t kDefaultFrameTimingBufferSize = 150; 67 static const size_t kDefaultFrameTimingBufferSize = 150;
69 static const size_t kServerTimingBufferSize = 150;
70 68
71 PerformanceBase::PerformanceBase(double time_origin, 69 PerformanceBase::PerformanceBase(double time_origin,
72 RefPtr<WebTaskRunner> task_runner) 70 RefPtr<WebTaskRunner> task_runner)
73 : frame_timing_buffer_size_(kDefaultFrameTimingBufferSize), 71 : frame_timing_buffer_size_(kDefaultFrameTimingBufferSize),
74 resource_timing_buffer_size_(kDefaultResourceTimingBufferSize), 72 resource_timing_buffer_size_(kDefaultResourceTimingBufferSize),
75 user_timing_(nullptr), 73 user_timing_(nullptr),
76 time_origin_(time_origin), 74 time_origin_(time_origin),
77 observer_filter_options_(PerformanceEntry::kInvalid), 75 observer_filter_options_(PerformanceEntry::kInvalid),
78 deliver_observations_timer_( 76 deliver_observations_timer_(
79 std::move(task_runner), 77 std::move(task_runner),
(...skipping 20 matching lines...) Expand all
100 // calls this method. 98 // calls this method.
101 if (navigation_timing_) 99 if (navigation_timing_)
102 entries.push_back(navigation_timing_); 100 entries.push_back(navigation_timing_);
103 entries.AppendVector(frame_timing_buffer_); 101 entries.AppendVector(frame_timing_buffer_);
104 102
105 if (user_timing_) { 103 if (user_timing_) {
106 entries.AppendVector(user_timing_->GetMarks()); 104 entries.AppendVector(user_timing_->GetMarks());
107 entries.AppendVector(user_timing_->GetMeasures()); 105 entries.AppendVector(user_timing_->GetMeasures());
108 } 106 }
109 107
110 entries.AppendVector(server_timing_buffer_);
111 if (first_paint_timing_) 108 if (first_paint_timing_)
112 entries.push_back(first_paint_timing_); 109 entries.push_back(first_paint_timing_);
113 if (first_contentful_paint_timing_) 110 if (first_contentful_paint_timing_)
114 entries.push_back(first_contentful_paint_timing_); 111 entries.push_back(first_contentful_paint_timing_);
115 112
116 std::sort(entries.begin(), entries.end(), 113 std::sort(entries.begin(), entries.end(),
117 PerformanceEntry::StartTimeCompareLessThan); 114 PerformanceEntry::StartTimeCompareLessThan);
118 return entries; 115 return entries;
119 } 116 }
120 117
(...skipping 23 matching lines...) Expand all
144 } 141 }
145 break; 142 break;
146 case PerformanceEntry::kMark: 143 case PerformanceEntry::kMark:
147 if (user_timing_) 144 if (user_timing_)
148 entries.AppendVector(user_timing_->GetMarks()); 145 entries.AppendVector(user_timing_->GetMarks());
149 break; 146 break;
150 case PerformanceEntry::kMeasure: 147 case PerformanceEntry::kMeasure:
151 if (user_timing_) 148 if (user_timing_)
152 entries.AppendVector(user_timing_->GetMeasures()); 149 entries.AppendVector(user_timing_->GetMeasures());
153 break; 150 break;
154 case PerformanceEntry::kServer:
155 entries.AppendVector(server_timing_buffer_);
156 break;
157 case PerformanceEntry::kPaint: 151 case PerformanceEntry::kPaint:
158 if (first_paint_timing_) 152 if (first_paint_timing_)
159 entries.push_back(first_paint_timing_); 153 entries.push_back(first_paint_timing_);
160 if (first_contentful_paint_timing_) 154 if (first_contentful_paint_timing_)
161 entries.push_back(first_contentful_paint_timing_); 155 entries.push_back(first_contentful_paint_timing_);
162 break; 156 break;
163 // Unsupported for LongTask, TaskAttribution. 157 // Unsupported for LongTask, TaskAttribution.
164 // Per the spec, these entries can only be accessed via 158 // Per the spec, these entries can only be accessed via
165 // Performance Observer. No separate buffer is maintained. 159 // Performance Observer. No separate buffer is maintained.
166 case PerformanceEntry::kLongTask: 160 case PerformanceEntry::kLongTask:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 } 203 }
210 } 204 }
211 205
212 if (user_timing_) { 206 if (user_timing_) {
213 if (entry_type.IsNull() || type == PerformanceEntry::kMark) 207 if (entry_type.IsNull() || type == PerformanceEntry::kMark)
214 entries.AppendVector(user_timing_->GetMarks(name)); 208 entries.AppendVector(user_timing_->GetMarks(name));
215 if (entry_type.IsNull() || type == PerformanceEntry::kMeasure) 209 if (entry_type.IsNull() || type == PerformanceEntry::kMeasure)
216 entries.AppendVector(user_timing_->GetMeasures(name)); 210 entries.AppendVector(user_timing_->GetMeasures(name));
217 } 211 }
218 212
219 if (entry_type.IsNull() || type == PerformanceEntry::kServer) {
220 // This is inefficient, but this buffer has a max size of
221 // 150 entries (controlled by kServerTimingBufferSize).
222 for (const auto& entry : server_timing_buffer_) {
223 if (entry->name() == name)
224 entries.push_back(entry);
225 }
226 }
227
228 std::sort(entries.begin(), entries.end(), 213 std::sort(entries.begin(), entries.end(),
229 PerformanceEntry::StartTimeCompareLessThan); 214 PerformanceEntry::StartTimeCompareLessThan);
230 return entries; 215 return entries;
231 } 216 }
232 217
233 void PerformanceBase::clearResourceTimings() { 218 void PerformanceBase::clearResourceTimings() {
234 resource_timing_buffer_.clear(); 219 resource_timing_buffer_.clear();
235 } 220 }
236 221
237 void PerformanceBase::setResourceTimingBufferSize(unsigned size) { 222 void PerformanceBase::setResourceTimingBufferSize(unsigned size) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 284
300 for (const ResourceResponse& response : redirect_chain) { 285 for (const ResourceResponse& response : redirect_chain) {
301 if (!PassesTimingAllowCheck(response, initiator_security_origin, 286 if (!PassesTimingAllowCheck(response, initiator_security_origin,
302 AtomicString(), context)) 287 AtomicString(), context))
303 return false; 288 return false;
304 } 289 }
305 290
306 return true; 291 return true;
307 } 292 }
308 293
309 void PerformanceBase::AddServerTiming(const ResourceResponse& response, 294 PerformanceServerTimingVector PerformanceBase::ParseServerTiming(
Yoav Weiss 2017/06/29 06:57:33 I think it'd make more sense to move this function
310 ShouldAddToBuffer shouldAddToBuffer) { 295 const ResourceTimingInfo& info,
311 if (shouldAddToBuffer == ShouldAddToBuffer::Never && 296 bool allowTimingDetails) {
312 !HasObserverFor(PerformanceEntry::kServer)) { 297 PerformanceServerTimingVector entries;
313 return; 298 if (RuntimeEnabledFeatures::ServerTimingEnabled()) {
299 const ResourceResponse& response = info.FinalResponse();
300 std::unique_ptr<ServerTimingHeaderVector> headers = ParseServerTimingHeader(
301 response.HttpHeaderField(HTTPNames::Server_Timing));
302 for (const auto& header : *headers) {
303 entries.push_back(
304 new PerformanceServerTiming(header->metric, header->value,
305 header->description, allowTimingDetails));
306 }
314 } 307 }
315 308 return entries;
316 ExecutionContext* context = GetExecutionContext();
317 SecurityOrigin* securityOrigin = GetSecurityOrigin(context);
318 if (!securityOrigin) {
319 return;
320 }
321 bool allowTimingDetails = PassesTimingAllowCheck(
322 response, *securityOrigin,
323 response.HttpHeaderField(HTTPNames::Timing_Allow_Origin), context);
324
325 std::unique_ptr<ServerTimingHeaderVector> headers = ParseServerTimingHeader(
326 response.HttpHeaderField(HTTPNames::Server_Timing));
327 if ((*headers).size() == 0) {
328 return;
329 }
330
331 PerformanceEntryVector entries;
332 for (const auto& header : *headers) {
333 PerformanceEntry* entry = PerformanceServerTiming::create(
334 response.Url().GetString(), header->metric,
335 allowTimingDetails ? header->duration : 0.0,
336 allowTimingDetails ? header->description : "");
337 entries.push_back(*entry);
338 }
339
340 NotifyObserversOfEntries(entries);
341 if (shouldAddToBuffer == ShouldAddToBuffer::Always &&
342 server_timing_buffer_.size() + entries.size() <=
343 kServerTimingBufferSize) {
344 server_timing_buffer_.AppendVector(entries);
345 }
346 } 309 }
347 310
348 void PerformanceBase::AddResourceTiming(const ResourceTimingInfo& info) { 311 void PerformanceBase::AddResourceTiming(const ResourceTimingInfo& info) {
349 if (IsResourceTimingBufferFull() && 312 if (IsResourceTimingBufferFull() &&
350 !HasObserverFor(PerformanceEntry::kResource)) 313 !HasObserverFor(PerformanceEntry::kResource))
351 return; 314 return;
352 ExecutionContext* context = GetExecutionContext(); 315 ExecutionContext* context = GetExecutionContext();
353 SecurityOrigin* security_origin = GetSecurityOrigin(context); 316 SecurityOrigin* security_origin = GetSecurityOrigin(context);
354 if (!security_origin) 317 if (!security_origin)
355 return; 318 return;
356 319
357 const ResourceResponse& final_response = info.FinalResponse(); 320 const ResourceResponse& final_response = info.FinalResponse();
358 bool allow_timing_details = 321 bool allow_timing_details =
359 PassesTimingAllowCheck(final_response, *security_origin, 322 PassesTimingAllowCheck(final_response, *security_origin,
360 info.OriginalTimingAllowOrigin(), context); 323 info.OriginalTimingAllowOrigin(), context);
361 double start_time = info.InitialTime(); 324 double start_time = info.InitialTime();
362 325
326 PerformanceServerTimingVector serverTiming =
327 ParseServerTiming(info, allow_timing_details);
328
363 if (info.RedirectChain().IsEmpty()) { 329 if (info.RedirectChain().IsEmpty()) {
364 PerformanceEntry* entry = PerformanceResourceTiming::Create( 330 PerformanceEntry* entry = PerformanceResourceTiming::Create(
365 info, TimeOrigin(), start_time, allow_timing_details); 331 info, TimeOrigin(), start_time, allow_timing_details, serverTiming);
366 NotifyObserversOfEntry(*entry); 332 NotifyObserversOfEntry(*entry);
367 if (!IsResourceTimingBufferFull()) 333 if (!IsResourceTimingBufferFull())
368 AddResourceTimingBuffer(*entry); 334 AddResourceTimingBuffer(*entry);
369 return; 335 return;
370 } 336 }
371 337
372 const Vector<ResourceResponse>& redirect_chain = info.RedirectChain(); 338 const Vector<ResourceResponse>& redirect_chain = info.RedirectChain();
373 bool allow_redirect_details = AllowsTimingRedirect( 339 bool allow_redirect_details = AllowsTimingRedirect(
374 redirect_chain, final_response, *security_origin, context); 340 redirect_chain, final_response, *security_origin, context);
375 341
376 if (!allow_redirect_details) { 342 if (!allow_redirect_details) {
377 ResourceLoadTiming* final_timing = final_response.GetResourceLoadTiming(); 343 ResourceLoadTiming* final_timing = final_response.GetResourceLoadTiming();
378 DCHECK(final_timing); 344 DCHECK(final_timing);
379 if (final_timing) 345 if (final_timing)
380 start_time = final_timing->RequestTime(); 346 start_time = final_timing->RequestTime();
381 } 347 }
382 348
383 ResourceLoadTiming* last_redirect_timing = 349 ResourceLoadTiming* last_redirect_timing =
384 redirect_chain.back().GetResourceLoadTiming(); 350 redirect_chain.back().GetResourceLoadTiming();
385 DCHECK(last_redirect_timing); 351 DCHECK(last_redirect_timing);
386 double last_redirect_end_time = last_redirect_timing->ReceiveHeadersEnd(); 352 double last_redirect_end_time = last_redirect_timing->ReceiveHeadersEnd();
387 353
388 PerformanceEntry* entry = PerformanceResourceTiming::Create( 354 PerformanceEntry* entry = PerformanceResourceTiming::Create(
389 info, TimeOrigin(), start_time, last_redirect_end_time, 355 info, TimeOrigin(), start_time, last_redirect_end_time,
390 allow_timing_details, allow_redirect_details); 356 allow_timing_details, allow_redirect_details, serverTiming);
391 NotifyObserversOfEntry(*entry); 357 NotifyObserversOfEntry(*entry);
392 if (!IsResourceTimingBufferFull()) 358 if (!IsResourceTimingBufferFull())
393 AddResourceTimingBuffer(*entry); 359 AddResourceTimingBuffer(*entry);
394 } 360 }
395 361
396 // Called after loadEventEnd happens. 362 // Called after loadEventEnd happens.
397 void PerformanceBase::NotifyNavigationTimingToObservers() { 363 void PerformanceBase::NotifyNavigationTimingToObservers() {
398 if (!navigation_timing_) 364 if (!navigation_timing_)
399 navigation_timing_ = CreateNavigationTimingInstance(); 365 navigation_timing_ = CreateNavigationTimingInstance();
400 if (navigation_timing_) 366 if (navigation_timing_)
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 571
606 DOMHighResTimeStamp PerformanceBase::now() const { 572 DOMHighResTimeStamp PerformanceBase::now() const {
607 return MonotonicTimeToDOMHighResTimeStamp(MonotonicallyIncreasingTime()); 573 return MonotonicTimeToDOMHighResTimeStamp(MonotonicallyIncreasingTime());
608 } 574 }
609 575
610 DEFINE_TRACE(PerformanceBase) { 576 DEFINE_TRACE(PerformanceBase) {
611 visitor->Trace(frame_timing_buffer_); 577 visitor->Trace(frame_timing_buffer_);
612 visitor->Trace(resource_timing_buffer_); 578 visitor->Trace(resource_timing_buffer_);
613 visitor->Trace(navigation_timing_); 579 visitor->Trace(navigation_timing_);
614 visitor->Trace(user_timing_); 580 visitor->Trace(user_timing_);
615 visitor->Trace(server_timing_buffer_);
616 visitor->Trace(first_paint_timing_); 581 visitor->Trace(first_paint_timing_);
617 visitor->Trace(first_contentful_paint_timing_); 582 visitor->Trace(first_contentful_paint_timing_);
618 visitor->Trace(observers_); 583 visitor->Trace(observers_);
619 visitor->Trace(active_observers_); 584 visitor->Trace(active_observers_);
620 visitor->Trace(suspended_observers_); 585 visitor->Trace(suspended_observers_);
621 EventTargetWithInlineData::Trace(visitor); 586 EventTargetWithInlineData::Trace(visitor);
622 } 587 }
623 588
624 } // namespace blink 589 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698