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

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

Issue 2647643004: Report nav timing 2 instance as soon as it's requested. (Closed)
Patch Set: make ResourceTimingInfo ref-counted Created 3 years, 10 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 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/timing/PerformanceNavigationTiming.h" 5 #include "core/timing/PerformanceNavigationTiming.h"
6 6
7 #include "bindings/core/v8/V8ObjectBuilder.h" 7 #include "bindings/core/v8/V8ObjectBuilder.h"
8 #include "core/dom/Document.h"
9 #include "core/dom/DocumentTiming.h"
10 #include "core/frame/LocalFrame.h"
11 #include "core/loader/DocumentLoadTiming.h"
12 #include "core/loader/DocumentLoader.h"
8 #include "core/timing/PerformanceBase.h" 13 #include "core/timing/PerformanceBase.h"
14 #include "platform/network/ResourceTimingInfo.h"
9 15
10 namespace blink { 16 namespace blink {
11 17
12 PerformanceNavigationTiming::PerformanceNavigationTiming( 18 PerformanceNavigationTiming::PerformanceNavigationTiming(
13 double timeOrigin, 19 LocalFrame* frame,
14 const String& requestedUrl, 20 ResourceTimingInfo* info,
Kunihiko Sakamoto 2017/02/13 08:22:29 Since this constructor takes ownership of the Reso
sunjian 2017/02/14 21:29:03 I don't want PerformanceNavigationTiming to own Re
Kunihiko Sakamoto 2017/02/15 06:35:30 But once ResourceFetcher has gone, PerformanceNavi
sunjian 2017/02/15 20:30:28 Doesn't PerformanceNavigationTiming become the own
Kunihiko Sakamoto 2017/02/16 08:42:29 Yeah ResourceTimingInfo* parameter will work, this
sunjian 2017/02/16 22:30:49 Acknowledged.
15 double unloadEventStart, 21 double timeOrigin)
16 double unloadEventEnd, 22 : PerformanceResourceTiming(info ? info->initialURL().getString() : "",
17 double loadEventStart,
18 double loadEventEnd,
19 unsigned short redirectCount,
20 double domInteractive,
21 double domContentLoadedEventStart,
22 double domContentLoadedEventEnd,
23 double domComplete,
24 NavigationType type,
25 double redirectStart,
26 double redirectEnd,
27 double fetchStart,
28 double responseEnd,
29 bool allowRedirectDetails,
30 bool hasSameOriginAsPreviousDocument,
31 ResourceLoadTiming* timing,
32 double lastRedirectEndTime,
33 double finishTime,
34 unsigned long long transferSize,
35 unsigned long long encodedBodyLength,
36 unsigned long long decodedBodyLength,
37 bool didReuseConnection)
38 : PerformanceResourceTiming("navigation",
39 timeOrigin,
40 timing,
41 lastRedirectEndTime,
42 finishTime,
43 transferSize,
44 encodedBodyLength,
45 decodedBodyLength,
46 didReuseConnection,
47 true /*allowTimingDetails*/, // TODO(sunjian):
48 // Create an enum
49 // for this.
50 allowRedirectDetails,
51 requestedUrl,
52 "navigation", 23 "navigation",
53 timeOrigin), 24 0.0,
25 0.0),
54 m_timeOrigin(timeOrigin), 26 m_timeOrigin(timeOrigin),
55 m_unloadEventStart(unloadEventStart), 27 m_resourceTimingInfo(info),
56 m_unloadEventEnd(unloadEventEnd), 28 m_frame(frame) {}
57 m_loadEventStart(loadEventStart),
58 m_loadEventEnd(loadEventEnd),
59 m_redirectCount(redirectCount),
60 m_domInteractive(domInteractive),
61 m_domContentLoadedEventStart(domContentLoadedEventStart),
62 m_domContentLoadedEventEnd(domContentLoadedEventEnd),
63 m_domComplete(domComplete),
64 m_type(type),
65 m_redirectStart(redirectStart),
66 m_redirectEnd(redirectEnd),
67 m_fetchStart(fetchStart),
68 m_responseEnd(responseEnd),
69 m_allowRedirectDetails(allowRedirectDetails),
70 m_hasSameOriginAsPreviousDocument(hasSameOriginAsPreviousDocument) {}
71 29
72 PerformanceNavigationTiming::~PerformanceNavigationTiming() {} 30 PerformanceNavigationTiming::~PerformanceNavigationTiming() {}
73 31
32 DEFINE_TRACE(PerformanceNavigationTiming) {
33 visitor->trace(m_frame);
34 PerformanceEntry::trace(visitor);
35 }
36
37 DocumentLoadTiming* PerformanceNavigationTiming::documentLoadTiming() const {
38 DocumentLoader* loader = documentLoader();
39 if (!loader)
40 return nullptr;
41
42 return &loader->timing();
43 }
44
45 DocumentLoader* PerformanceNavigationTiming::documentLoader() const {
46 if (!m_frame)
47 return nullptr;
48
49 return m_frame->loader().documentLoader();
50 }
51
52 const DocumentTiming* PerformanceNavigationTiming::documentTiming() const {
53 if (!m_frame)
54 return nullptr;
55
56 Document* document = m_frame->document();
57 if (!document)
58 return nullptr;
59
60 return &document->timing();
61 }
62
63 ResourceLoadTiming* PerformanceNavigationTiming::resourceLoadTiming() const {
64 if (!m_resourceTimingInfo)
65 return nullptr;
66 return m_resourceTimingInfo->finalResponse().resourceLoadTiming();
67 }
68
69 ExecutionContext* PerformanceNavigationTiming::getExecutionContext() const {
70 return m_frame ? m_frame->document() : nullptr;
71 }
72
73 bool PerformanceNavigationTiming::getAllowRedirectDetails() const {
Kunihiko Sakamoto 2017/02/13 08:22:29 Can you precompute this in the constructor and sto
sunjian 2017/02/14 21:29:03 That would be ideal. But we don't know exactly whe
Kunihiko Sakamoto 2017/02/15 06:35:30 Does that mean this function could return differen
sunjian 2017/02/15 20:30:28 If we can get the final response at construction t
panicker 2017/02/16 00:37:23 Can we add an explicit check here with a comment:
Kunihiko Sakamoto 2017/02/16 08:42:29 So unloadEventStart, unloadEventEnd, redirectCount
sunjian 2017/02/16 22:30:49 I don't think there is a reasonable way to tell if
sunjian 2017/02/16 22:30:49 As far as i know, NT1 kind of has the same problem
74 ExecutionContext* context = getExecutionContext();
75 SecurityOrigin* securityOrigin = nullptr;
76 if (context)
77 securityOrigin = context->getSecurityOrigin();
78 if (!securityOrigin)
79 return false;
80 if (!m_resourceTimingInfo)
81 return false;
82
83 return PerformanceBase::allowsTimingRedirect(
84 m_resourceTimingInfo->redirectChain(),
85 m_resourceTimingInfo->finalResponse(), *securityOrigin, context);
86 }
87
74 DOMHighResTimeStamp PerformanceNavigationTiming::unloadEventStart() const { 88 DOMHighResTimeStamp PerformanceNavigationTiming::unloadEventStart() const {
75 if (!m_allowRedirectDetails || !m_hasSameOriginAsPreviousDocument) 89 bool allowRedirectDetails = getAllowRedirectDetails();
76 return 0; 90 DocumentLoadTiming* timing = documentLoadTiming();
77 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( 91
78 m_timeOrigin, m_unloadEventStart); 92 if (!allowRedirectDetails || !timing ||
93 !timing->hasSameOriginAsPreviousDocument())
94 return 0;
95 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
96 m_timeOrigin, timing->unloadEventStart());
79 } 97 }
80 98
81 DOMHighResTimeStamp PerformanceNavigationTiming::unloadEventEnd() const { 99 DOMHighResTimeStamp PerformanceNavigationTiming::unloadEventEnd() const {
82 if (!m_allowRedirectDetails || !m_hasSameOriginAsPreviousDocument) 100 bool allowRedirectDetails = getAllowRedirectDetails();
83 return 0; 101 DocumentLoadTiming* timing = documentLoadTiming();
84 102
85 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, 103 if (!allowRedirectDetails || !timing ||
86 m_unloadEventEnd); 104 !timing->hasSameOriginAsPreviousDocument())
105 return 0;
106 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
107 m_timeOrigin, timing->unloadEventEnd());
87 } 108 }
88 109
89 DOMHighResTimeStamp PerformanceNavigationTiming::domInteractive() const { 110 DOMHighResTimeStamp PerformanceNavigationTiming::domInteractive() const {
90 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, 111 const DocumentTiming* timing = documentTiming();
91 m_domInteractive); 112 if (!timing)
113 return 0.0;
114 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
115 m_timeOrigin, timing->domInteractive());
92 } 116 }
93 117
94 DOMHighResTimeStamp PerformanceNavigationTiming::domContentLoadedEventStart() 118 DOMHighResTimeStamp PerformanceNavigationTiming::domContentLoadedEventStart()
95 const { 119 const {
96 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( 120 const DocumentTiming* timing = documentTiming();
97 m_timeOrigin, m_domContentLoadedEventStart); 121 if (!timing)
122 return 0.0;
123 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
124 m_timeOrigin, timing->domContentLoadedEventStart());
98 } 125 }
99 126
100 DOMHighResTimeStamp PerformanceNavigationTiming::domContentLoadedEventEnd() 127 DOMHighResTimeStamp PerformanceNavigationTiming::domContentLoadedEventEnd()
101 const { 128 const {
102 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( 129 const DocumentTiming* timing = documentTiming();
103 m_timeOrigin, m_domContentLoadedEventEnd); 130 if (!timing)
131 return 0.0;
132 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
133 m_timeOrigin, timing->domContentLoadedEventEnd());
104 } 134 }
105 135
106 DOMHighResTimeStamp PerformanceNavigationTiming::domComplete() const { 136 DOMHighResTimeStamp PerformanceNavigationTiming::domComplete() const {
107 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, 137 const DocumentTiming* timing = documentTiming();
108 m_domComplete); 138 if (!timing)
139 return 0.0;
140 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
141 m_timeOrigin, timing->domComplete());
109 } 142 }
110 143
111 DOMHighResTimeStamp PerformanceNavigationTiming::loadEventStart() const { 144 DOMHighResTimeStamp PerformanceNavigationTiming::loadEventStart() const {
112 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, 145 DocumentLoadTiming* timing = documentLoadTiming();
113 m_loadEventStart); 146 if (!timing)
147 return 0.0;
148 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
149 m_timeOrigin, timing->loadEventStart());
114 } 150 }
115 151
116 DOMHighResTimeStamp PerformanceNavigationTiming::loadEventEnd() const { 152 DOMHighResTimeStamp PerformanceNavigationTiming::loadEventEnd() const {
117 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, 153 DocumentLoadTiming* timing = documentLoadTiming();
118 m_loadEventEnd); 154 if (!timing)
119 } 155 return 0.0;
120 156 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
121 AtomicString PerformanceNavigationTiming::type() const { 157 m_timeOrigin, timing->loadEventEnd());
122 switch (m_type) { 158 }
123 case NavigationType::Reload: 159
160 AtomicString PerformanceNavigationTiming::getNavigationType(
161 NavigationType type,
162 const Document* document) {
163 if (document &&
164 document->pageVisibilityState() == PageVisibilityStatePrerender) {
165 return "prerender";
166 }
167 switch (type) {
168 case NavigationTypeReload:
124 return "reload"; 169 return "reload";
125 case NavigationType::BackForward: 170 case NavigationTypeBackForward:
126 return "back_forward"; 171 return "back_forward";
127 case NavigationType::Prerender: 172 case NavigationTypeLinkClicked:
128 return "prerender"; 173 case NavigationTypeFormSubmitted:
129 case NavigationType::Navigate: 174 case NavigationTypeFormResubmitted:
175 case NavigationTypeOther:
130 return "navigate"; 176 return "navigate";
131 } 177 }
132 NOTREACHED(); 178 NOTREACHED();
133 return "navigate"; 179 return "navigate";
134 } 180 }
135 181
182 AtomicString PerformanceNavigationTiming::type() const {
183 DocumentLoader* loader = documentLoader();
184 if (!m_frame || !loader)
185 return ""; // Not available yet.
Kunihiko Sakamoto 2017/02/13 08:22:29 Can this happen? I think navigation type should be
sunjian 2017/02/14 21:29:03 You are probably right. I'll go ahead and replace
186 Document* document = m_frame->document();
187 return getNavigationType(loader->getNavigationType(), document);
188 }
189
136 unsigned short PerformanceNavigationTiming::redirectCount() const { 190 unsigned short PerformanceNavigationTiming::redirectCount() const {
137 if (!m_allowRedirectDetails) 191 bool allowRedirectDetails = getAllowRedirectDetails();
138 return 0; 192 DocumentLoadTiming* timing = documentLoadTiming();
139 return m_redirectCount; 193 if (!allowRedirectDetails || !timing)
194 return 0;
195 return timing->redirectCount();
196 }
197
198 // Overriding PerformanceResourceTiming's attributes.
199 AtomicString PerformanceNavigationTiming::initiatorType() const {
200 return "navigation";
201 }
202
203 DOMHighResTimeStamp PerformanceNavigationTiming::workerStart() const {
Kunihiko Sakamoto 2017/02/13 08:22:29 Can we reduce code duplication between Performance
Kunihiko Sakamoto 2017/02/13 08:27:40 Or even simpler: // Overridden by PerformanceReso
sunjian 2017/02/14 21:29:03 Done.
sunjian 2017/02/14 21:29:03 Acknowledged.
204 ResourceLoadTiming* timing = resourceLoadTiming();
205 if (!timing || timing->workerStart() == 0.0)
206 return 0.0;
207 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
208 m_timeOrigin, timing->workerStart());
209 }
210
211 DOMHighResTimeStamp PerformanceNavigationTiming::redirectStart() const {
212 bool allowRedirectDetails = getAllowRedirectDetails();
213 DocumentLoadTiming* timing = documentLoadTiming();
214 if (!allowRedirectDetails || !timing)
215 return 0;
216 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
217 m_timeOrigin, timing->redirectStart());
218 }
219
220 DOMHighResTimeStamp PerformanceNavigationTiming::redirectEnd() const {
221 bool allowRedirectDetails = getAllowRedirectDetails();
222 DocumentLoadTiming* timing = documentLoadTiming();
223 if (!allowRedirectDetails || !timing)
224 return 0;
225 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
226 m_timeOrigin, timing->redirectEnd());
140 } 227 }
141 228
142 DOMHighResTimeStamp PerformanceNavigationTiming::fetchStart() const { 229 DOMHighResTimeStamp PerformanceNavigationTiming::fetchStart() const {
230 DocumentLoadTiming* timing = documentLoadTiming();
231 if (!timing)
232 return 0.0;
233 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
234 m_timeOrigin, timing->fetchStart());
235 }
236
237 DOMHighResTimeStamp PerformanceNavigationTiming::domainLookupStart() const {
238 ResourceLoadTiming* timing = resourceLoadTiming();
239 if (!timing || timing->dnsStart() == 0.0)
240 return fetchStart();
241 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
242 m_timeOrigin, timing->dnsStart());
243 }
244
245 DOMHighResTimeStamp PerformanceNavigationTiming::domainLookupEnd() const {
246 ResourceLoadTiming* timing = resourceLoadTiming();
247 if (!timing || timing->dnsEnd() == 0.0)
248 return domainLookupStart();
143 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, 249 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin,
144 m_fetchStart); 250 timing->dnsEnd());
145 } 251 }
146 252
147 DOMHighResTimeStamp PerformanceNavigationTiming::redirectStart() const { 253 DOMHighResTimeStamp PerformanceNavigationTiming::connectStart() const {
148 if (!m_allowRedirectDetails) 254 DocumentLoader* loader = documentLoader();
149 return 0; 255 if (!loader)
256 return domainLookupEnd();
257 ResourceLoadTiming* timing = resourceLoadTiming();
258 if (!timing || timing->connectStart() == 0.0 ||
259 m_resourceTimingInfo->finalResponse().connectionReused())
260 return domainLookupEnd();
261 double connectStart = timing->connectStart();
262 if (timing->dnsEnd() > 0.0 && timing->dnsEnd() > connectStart)
263 connectStart = timing->dnsEnd();
264
150 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, 265 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin,
151 m_redirectStart); 266 connectStart);
152 } 267 }
153 268
154 DOMHighResTimeStamp PerformanceNavigationTiming::redirectEnd() const { 269 DOMHighResTimeStamp PerformanceNavigationTiming::connectEnd() const {
155 if (!m_allowRedirectDetails) 270 DocumentLoader* loader = documentLoader();
156 return 0; 271 if (!loader)
157 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, 272 return connectStart();
158 m_redirectEnd); 273 ResourceLoadTiming* timing = resourceLoadTiming();
274 if (!timing || timing->connectEnd() == 0.0 ||
275 m_resourceTimingInfo->finalResponse().connectionReused())
276 return connectStart();
277 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
278 m_timeOrigin, timing->connectEnd());
279 }
280
281 DOMHighResTimeStamp PerformanceNavigationTiming::secureConnectionStart() const {
282 DocumentLoader* loader = documentLoader();
283 if (!loader)
284 return 0.0;
285 ResourceLoadTiming* timing = resourceLoadTiming();
286 if (!timing ||
287 timing->sslStart() == 0.0) // Secure connection not negotiated.
288 return 0.0;
289 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
290 m_timeOrigin, timing->sslStart());
291 }
292
293 DOMHighResTimeStamp PerformanceNavigationTiming::requestStart() const {
294 ResourceLoadTiming* timing = resourceLoadTiming();
295 if (!timing || timing->sendStart() == 0.0)
296 return connectEnd();
297 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
298 m_timeOrigin, timing->sendStart());
299 }
300
301 DOMHighResTimeStamp PerformanceNavigationTiming::responseStart() const {
302 ResourceLoadTiming* timing = resourceLoadTiming();
303 if (!timing || timing->receiveHeadersEnd() == 0.0)
304 return requestStart();
305 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
306 m_timeOrigin, timing->receiveHeadersEnd());
159 } 307 }
160 308
161 DOMHighResTimeStamp PerformanceNavigationTiming::responseEnd() const { 309 DOMHighResTimeStamp PerformanceNavigationTiming::responseEnd() const {
162 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, 310 DocumentLoadTiming* timing = documentLoadTiming();
163 m_responseEnd); 311 if (!timing)
312 return 0.0;
313 return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
314 m_timeOrigin, timing->responseEnd());
315 }
316
317 unsigned long long PerformanceNavigationTiming::transferSize() const {
318 return !m_resourceTimingInfo ? 0 : m_resourceTimingInfo->transferSize();
319 }
320
321 unsigned long long PerformanceNavigationTiming::encodedBodySize() const {
322 return !m_resourceTimingInfo
323 ? 0
324 : m_resourceTimingInfo->finalResponse().encodedBodyLength();
325 }
326
327 unsigned long long PerformanceNavigationTiming::decodedBodySize() const {
328 return !m_resourceTimingInfo
329 ? 0
330 : m_resourceTimingInfo->finalResponse().decodedBodyLength();
331 }
332
333 // Overriding PerformanceEntry's attributes.
334 DOMHighResTimeStamp PerformanceNavigationTiming::duration() const {
335 return loadEventEnd();
164 } 336 }
165 337
166 void PerformanceNavigationTiming::buildJSONValue( 338 void PerformanceNavigationTiming::buildJSONValue(
167 V8ObjectBuilder& builder) const { 339 V8ObjectBuilder& builder) const {
168 PerformanceResourceTiming::buildJSONValue(builder); 340 PerformanceResourceTiming::buildJSONValue(builder);
169 builder.addNumber("unloadEventStart", unloadEventStart()); 341 builder.addNumber("unloadEventStart", unloadEventStart());
170 builder.addNumber("unloadEventEnd", unloadEventEnd()); 342 builder.addNumber("unloadEventEnd", unloadEventEnd());
171 builder.addNumber("domInteractive", domInteractive()); 343 builder.addNumber("domInteractive", domInteractive());
172 builder.addNumber("domContentLoadedEventStart", domContentLoadedEventStart()); 344 builder.addNumber("domContentLoadedEventStart", domContentLoadedEventStart());
173 builder.addNumber("domContentLoadedEventEnd", domContentLoadedEventEnd()); 345 builder.addNumber("domContentLoadedEventEnd", domContentLoadedEventEnd());
174 builder.addNumber("domComplete", domComplete()); 346 builder.addNumber("domComplete", domComplete());
175 builder.addNumber("loadEventStart", loadEventStart()); 347 builder.addNumber("loadEventStart", loadEventStart());
176 builder.addNumber("loadEventEnd", loadEventEnd()); 348 builder.addNumber("loadEventEnd", loadEventEnd());
177 builder.addString("type", type()); 349 builder.addString("type", type());
178 builder.addNumber("redirectCount", redirectCount()); 350 builder.addNumber("redirectCount", redirectCount());
179 } 351 }
180 } 352 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698