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

Side by Side Diff: components/page_load_metrics/renderer/metrics_render_frame_observer.cc

Issue 2177743002: Migrate page_load_metrics out of components. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: migrate page_load_metrics_messages to common message generator Created 4 years, 4 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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/page_load_metrics/renderer/metrics_render_frame_observer.h"
6
7 #include <string>
8
9 #include "base/memory/ptr_util.h"
10 #include "base/time/time.h"
11 #include "base/timer/timer.h"
12 #include "components/page_load_metrics/renderer/page_timing_metrics_sender.h"
13 #include "content/public/renderer/render_frame.h"
14 #include "third_party/WebKit/public/platform/WebURLResponse.h"
15 #include "third_party/WebKit/public/web/WebDataSource.h"
16 #include "third_party/WebKit/public/web/WebDocument.h"
17 #include "third_party/WebKit/public/web/WebLocalFrame.h"
18 #include "third_party/WebKit/public/web/WebPerformance.h"
19 #include "url/gurl.h"
20
21 namespace page_load_metrics {
22
23 namespace {
24
25 base::TimeDelta ClampDelta(double event, double start) {
26 if (event - start < 0)
27 event = start;
28 return base::Time::FromDoubleT(event) - base::Time::FromDoubleT(start);
29 }
30
31 } // namespace
32
33 MetricsRenderFrameObserver::MetricsRenderFrameObserver(
34 content::RenderFrame* render_frame)
35 : content::RenderFrameObserver(render_frame) {}
36
37 MetricsRenderFrameObserver::~MetricsRenderFrameObserver() {}
38
39 void MetricsRenderFrameObserver::DidChangePerformanceTiming() {
40 SendMetrics();
41 }
42
43 void MetricsRenderFrameObserver::DidObserveLoadingBehavior(
44 blink::WebLoadingBehaviorFlag behavior) {
45 if (page_timing_metrics_sender_)
46 page_timing_metrics_sender_->DidObserveLoadingBehavior(behavior);
47 }
48
49 void MetricsRenderFrameObserver::DidCommitProvisionalLoad(
50 bool is_new_navigation,
51 bool is_same_page_navigation) {
52 // Same-page navigations (e.g. an in-document navigation from a fragment
53 // link) aren't full page loads, since they don't go to network to load the
54 // main HTML resource. DidStartProvisionalLoad doesn't get invoked for same
55 // page navigations, so we may still have an active
56 // page_timing_metrics_sender_ at this point.
57 if (is_same_page_navigation)
58 return;
59
60 // Make sure to release the sender for a previous navigation, if we have one.
61 page_timing_metrics_sender_.reset();
62
63 // We only create a PageTimingMetricsSender if the page meets the criteria for
64 // sending and recording metrics. Once page_timing_metrics_sender_ is
65 // non-null, we will send metrics for the current page at some later time, as
66 // those metrics become available.
67 if (ShouldSendMetrics()) {
68 PageLoadTiming timing(GetTiming());
69 DCHECK(!timing.navigation_start.is_null());
70 page_timing_metrics_sender_.reset(
71 new PageTimingMetricsSender(this, routing_id(), CreateTimer(), timing));
72 }
73 }
74
75 void MetricsRenderFrameObserver::SendMetrics() {
76 if (!page_timing_metrics_sender_)
77 return;
78 if (HasNoRenderFrame())
79 return;
80 PageLoadTiming timing(GetTiming());
81 page_timing_metrics_sender_->Send(timing);
82 }
83
84 bool MetricsRenderFrameObserver::ShouldSendMetrics() const {
85 if (HasNoRenderFrame())
86 return false;
87 const blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
88 // We only generate historgrams for main frames.
89 if (frame->parent())
90 return false;
91
92 const blink::WebDocument& document = frame->document();
93 // Ignore non-HTTP schemes (e.g. chrome://).
94 const GURL& url = document.url();
95 if (!url.SchemeIsHTTPOrHTTPS())
96 return false;
97
98 const blink::WebURLResponse& url_response = frame->dataSource()->response();
99
100 // Ignore non-HTML documents (e.g. SVG). Note that images are treated by
101 // Blink as HTML documents, so to exclude images, we must perform
102 // additional mime type checking below.
103 if (!document.isHTMLDocument() && !document.isXHTMLDocument())
104 return false;
105
106 // Ignore non-HTML mime types (e.g. images).
107 std::string mime_type = url_response.mimeType().utf8();
108 if (mime_type != "text/html" && mime_type != "application/xhtml+xml")
109 return false;
110
111 return true;
112 }
113
114 PageLoadTiming MetricsRenderFrameObserver::GetTiming() const {
115 const blink::WebPerformance& perf =
116 render_frame()->GetWebFrame()->performance();
117
118 PageLoadTiming timing;
119 double start = perf.navigationStart();
120 timing.navigation_start = base::Time::FromDoubleT(start);
121 if (perf.responseStart() > 0.0)
122 timing.response_start = ClampDelta(perf.responseStart(), start);
123 if (perf.domLoading() > 0.0)
124 timing.dom_loading = ClampDelta(perf.domLoading(), start);
125 if (perf.domContentLoadedEventStart() > 0.0)
126 timing.dom_content_loaded_event_start =
127 ClampDelta(perf.domContentLoadedEventStart(), start);
128 if (perf.loadEventStart() > 0.0)
129 timing.load_event_start = ClampDelta(perf.loadEventStart(), start);
130 if (perf.firstLayout() > 0.0)
131 timing.first_layout = ClampDelta(perf.firstLayout(), start);
132 if (perf.firstPaint() > 0.0)
133 timing.first_paint = ClampDelta(perf.firstPaint(), start);
134 if (perf.firstTextPaint() > 0.0)
135 timing.first_text_paint = ClampDelta(perf.firstTextPaint(), start);
136 if (perf.firstImagePaint() > 0.0)
137 timing.first_image_paint = ClampDelta(perf.firstImagePaint(), start);
138 if (perf.firstContentfulPaint() > 0.0)
139 timing.first_contentful_paint =
140 ClampDelta(perf.firstContentfulPaint(), start);
141 if (perf.parseStart() > 0.0)
142 timing.parse_start = ClampDelta(perf.parseStart(), start);
143 if (perf.parseStop() > 0.0)
144 timing.parse_stop = ClampDelta(perf.parseStop(), start);
145 if (timing.parse_start) {
146 // If we started parsing, record all parser durations such as the amount of
147 // time blocked on script load, even if those values are zero.
148 timing.parse_blocked_on_script_load_duration =
149 base::TimeDelta::FromSecondsD(perf.parseBlockedOnScriptLoadDuration());
150 timing.parse_blocked_on_script_load_from_document_write_duration =
151 base::TimeDelta::FromSecondsD(
152 perf.parseBlockedOnScriptLoadFromDocumentWriteDuration());
153 }
154 return timing;
155 }
156
157 std::unique_ptr<base::Timer> MetricsRenderFrameObserver::CreateTimer() const {
158 return base::WrapUnique(new base::OneShotTimer);
159 }
160
161 bool MetricsRenderFrameObserver::HasNoRenderFrame() const {
162 bool no_frame = !render_frame() || !render_frame()->GetWebFrame();
163 DCHECK(!no_frame);
164 return no_frame;
165 }
166
167 void MetricsRenderFrameObserver::OnDestruct() {
168 delete this;
169 }
170
171 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698