OLD | NEW |
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 "chrome/browser/page_load_metrics/observers/amp_page_load_metrics_obser
ver.h" | 5 #include "chrome/browser/page_load_metrics/observers/amp_page_load_metrics_obser
ver.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/optional.h" | 9 #include "base/optional.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 .append(name), \ | 51 .append(name), \ |
52 value); \ | 52 value); \ |
53 break; \ | 53 break; \ |
54 case AMPViewType::GOOGLE_NEWS_AMP_VIEWER: \ | 54 case AMPViewType::GOOGLE_NEWS_AMP_VIEWER: \ |
55 PAGE_LOAD_HISTOGRAM( \ | 55 PAGE_LOAD_HISTOGRAM( \ |
56 std::string(kHistogramPrefix).append("GoogleNews.").append(name), \ | 56 std::string(kHistogramPrefix).append("GoogleNews.").append(name), \ |
57 value); \ | 57 value); \ |
58 break; \ | 58 break; \ |
59 case AMPViewType::NONE: \ | 59 case AMPViewType::NONE: \ |
60 NOTREACHED(); \ | 60 NOTREACHED(); \ |
| 61 case AMPViewType::AMP_VIEW_TYPE_LAST: \ |
61 break; \ | 62 break; \ |
62 } \ | 63 } \ |
63 } while (false) | 64 } while (false) |
64 | 65 |
| 66 GURL GetCanonicalizedSameDocumentUrl(const GURL& url) { |
| 67 if (!url.has_ref()) |
| 68 return url; |
| 69 |
| 70 // We're only interested in same document navigations where the full URL |
| 71 // changes, so we ignore the 'ref' or '#fragment' portion of the URL. |
| 72 GURL::Replacements replacements; |
| 73 replacements.ClearRef(); |
| 74 return url.ReplaceComponents(replacements); |
| 75 } |
| 76 |
65 } // namespace | 77 } // namespace |
66 | 78 |
67 AMPPageLoadMetricsObserver::AMPPageLoadMetricsObserver() {} | 79 AMPPageLoadMetricsObserver::AMPPageLoadMetricsObserver() {} |
68 | 80 |
69 AMPPageLoadMetricsObserver::~AMPPageLoadMetricsObserver() {} | 81 AMPPageLoadMetricsObserver::~AMPPageLoadMetricsObserver() {} |
70 | 82 |
71 page_load_metrics::PageLoadMetricsObserver::ObservePolicy | 83 page_load_metrics::PageLoadMetricsObserver::ObservePolicy |
72 AMPPageLoadMetricsObserver::OnCommit( | 84 AMPPageLoadMetricsObserver::OnCommit( |
73 content::NavigationHandle* navigation_handle) { | 85 content::NavigationHandle* navigation_handle) { |
74 view_type_ = GetAMPViewType(navigation_handle->GetURL()); | 86 current_url_ = navigation_handle->GetURL(); |
75 return (view_type_ != AMPViewType::NONE) ? CONTINUE_OBSERVING | 87 view_type_ = GetAMPViewType(current_url_); |
76 : STOP_OBSERVING; | 88 return CONTINUE_OBSERVING; |
| 89 } |
| 90 |
| 91 void AMPPageLoadMetricsObserver::OnCommitSameDocumentNavigation( |
| 92 content::NavigationHandle* navigation_handle) { |
| 93 const GURL url = GetCanonicalizedSameDocumentUrl(navigation_handle->GetURL()); |
| 94 |
| 95 // Ignore same document navigations where the URL doesn't change. |
| 96 if (url == current_url_) |
| 97 return; |
| 98 current_url_ = url; |
| 99 |
| 100 AMPViewType same_document_view_type = GetAMPViewType(url); |
| 101 if (same_document_view_type == AMPViewType::NONE) |
| 102 return; |
| 103 |
| 104 // Though we're not currently able to track page load metrics such as FCP for |
| 105 // same-document navigations, we can count how often they happen, to better |
| 106 // understand the relative frequency of same-document vs new-document AMP |
| 107 // navigations. |
| 108 UMA_HISTOGRAM_ENUMERATION( |
| 109 std::string(kHistogramPrefix).append("SameDocumentView"), |
| 110 same_document_view_type, AMPViewType::AMP_VIEW_TYPE_LAST); |
77 } | 111 } |
78 | 112 |
79 void AMPPageLoadMetricsObserver::OnDomContentLoadedEventStart( | 113 void AMPPageLoadMetricsObserver::OnDomContentLoadedEventStart( |
80 const page_load_metrics::PageLoadTiming& timing, | 114 const page_load_metrics::PageLoadTiming& timing, |
81 const page_load_metrics::PageLoadExtraInfo& info) { | 115 const page_load_metrics::PageLoadExtraInfo& info) { |
| 116 if (view_type_ == AMPViewType::NONE) |
| 117 return; |
| 118 |
82 if (!WasStartedInForegroundOptionalEventInForeground( | 119 if (!WasStartedInForegroundOptionalEventInForeground( |
83 timing.document_timing.dom_content_loaded_event_start, info)) { | 120 timing.document_timing.dom_content_loaded_event_start, info)) { |
84 return; | 121 return; |
85 } | 122 } |
86 RECORD_HISTOGRAM_FOR_TYPE( | 123 RECORD_HISTOGRAM_FOR_TYPE( |
87 kHistogramAMPDOMContentLoadedEventFired, view_type_, | 124 kHistogramAMPDOMContentLoadedEventFired, view_type_, |
88 timing.document_timing.dom_content_loaded_event_start.value()); | 125 timing.document_timing.dom_content_loaded_event_start.value()); |
89 } | 126 } |
90 | 127 |
91 void AMPPageLoadMetricsObserver::OnLoadEventStart( | 128 void AMPPageLoadMetricsObserver::OnLoadEventStart( |
92 const page_load_metrics::PageLoadTiming& timing, | 129 const page_load_metrics::PageLoadTiming& timing, |
93 const page_load_metrics::PageLoadExtraInfo& info) { | 130 const page_load_metrics::PageLoadExtraInfo& info) { |
| 131 if (view_type_ == AMPViewType::NONE) |
| 132 return; |
| 133 |
94 if (!WasStartedInForegroundOptionalEventInForeground( | 134 if (!WasStartedInForegroundOptionalEventInForeground( |
95 timing.document_timing.load_event_start, info)) { | 135 timing.document_timing.load_event_start, info)) { |
96 return; | 136 return; |
97 } | 137 } |
98 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPLoadEventFired, view_type_, | 138 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPLoadEventFired, view_type_, |
99 timing.document_timing.load_event_start.value()); | 139 timing.document_timing.load_event_start.value()); |
100 } | 140 } |
101 | 141 |
102 void AMPPageLoadMetricsObserver::OnFirstLayout( | 142 void AMPPageLoadMetricsObserver::OnFirstLayout( |
103 const page_load_metrics::PageLoadTiming& timing, | 143 const page_load_metrics::PageLoadTiming& timing, |
104 const page_load_metrics::PageLoadExtraInfo& info) { | 144 const page_load_metrics::PageLoadExtraInfo& info) { |
| 145 if (view_type_ == AMPViewType::NONE) |
| 146 return; |
| 147 |
105 if (!WasStartedInForegroundOptionalEventInForeground( | 148 if (!WasStartedInForegroundOptionalEventInForeground( |
106 timing.document_timing.first_layout, info)) { | 149 timing.document_timing.first_layout, info)) { |
107 return; | 150 return; |
108 } | 151 } |
109 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPFirstLayout, view_type_, | 152 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPFirstLayout, view_type_, |
110 timing.document_timing.first_layout.value()); | 153 timing.document_timing.first_layout.value()); |
111 } | 154 } |
112 | 155 |
113 void AMPPageLoadMetricsObserver::OnFirstContentfulPaintInPage( | 156 void AMPPageLoadMetricsObserver::OnFirstContentfulPaintInPage( |
114 const page_load_metrics::PageLoadTiming& timing, | 157 const page_load_metrics::PageLoadTiming& timing, |
115 const page_load_metrics::PageLoadExtraInfo& info) { | 158 const page_load_metrics::PageLoadExtraInfo& info) { |
| 159 if (view_type_ == AMPViewType::NONE) |
| 160 return; |
| 161 |
116 if (!WasStartedInForegroundOptionalEventInForeground( | 162 if (!WasStartedInForegroundOptionalEventInForeground( |
117 timing.paint_timing.first_contentful_paint, info)) { | 163 timing.paint_timing.first_contentful_paint, info)) { |
118 return; | 164 return; |
119 } | 165 } |
120 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPFirstContentfulPaint, view_type_, | 166 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPFirstContentfulPaint, view_type_, |
121 timing.paint_timing.first_contentful_paint.value()); | 167 timing.paint_timing.first_contentful_paint.value()); |
122 } | 168 } |
123 | 169 |
124 void AMPPageLoadMetricsObserver::OnParseStart( | 170 void AMPPageLoadMetricsObserver::OnParseStart( |
125 const page_load_metrics::PageLoadTiming& timing, | 171 const page_load_metrics::PageLoadTiming& timing, |
126 const page_load_metrics::PageLoadExtraInfo& info) { | 172 const page_load_metrics::PageLoadExtraInfo& info) { |
| 173 if (view_type_ == AMPViewType::NONE) |
| 174 return; |
| 175 |
127 if (!WasStartedInForegroundOptionalEventInForeground( | 176 if (!WasStartedInForegroundOptionalEventInForeground( |
128 timing.parse_timing.parse_start, info)) { | 177 timing.parse_timing.parse_start, info)) { |
129 return; | 178 return; |
130 } | 179 } |
131 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPParseStart, view_type_, | 180 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPParseStart, view_type_, |
132 timing.parse_timing.parse_start.value()); | 181 timing.parse_timing.parse_start.value()); |
133 } | 182 } |
134 | 183 |
135 // static | 184 // static |
136 AMPPageLoadMetricsObserver::AMPViewType | 185 AMPPageLoadMetricsObserver::AMPViewType |
137 AMPPageLoadMetricsObserver::GetAMPViewType(const GURL& url) { | 186 AMPPageLoadMetricsObserver::GetAMPViewType(const GURL& url) { |
| 187 const char kAmpViewerUrlPrefix[] = "/amp/"; |
| 188 |
138 if (base::EndsWith(url.host(), kAmpCacheHostSuffix, | 189 if (base::EndsWith(url.host(), kAmpCacheHostSuffix, |
139 base::CompareCase::INSENSITIVE_ASCII)) { | 190 base::CompareCase::INSENSITIVE_ASCII)) { |
140 return AMPViewType::AMP_CACHE; | 191 return AMPViewType::AMP_CACHE; |
141 } | 192 } |
142 | 193 |
143 base::Optional<std::string> google_hostname_prefix = | 194 base::Optional<std::string> google_hostname_prefix = |
144 page_load_metrics::GetGoogleHostnamePrefix(url); | 195 page_load_metrics::GetGoogleHostnamePrefix(url); |
145 if (!google_hostname_prefix.has_value()) | 196 if (!google_hostname_prefix.has_value()) |
146 return AMPViewType::NONE; | 197 return AMPViewType::NONE; |
147 | 198 |
148 if (google_hostname_prefix.value() == "www" && | 199 if (google_hostname_prefix.value() == "www" && |
149 base::StartsWith(url.path_piece(), "/amp/", | 200 base::StartsWith(url.path_piece(), kAmpViewerUrlPrefix, |
150 base::CompareCase::SENSITIVE)) { | 201 base::CompareCase::SENSITIVE) && |
| 202 url.path_piece().length() > strlen(kAmpViewerUrlPrefix)) { |
151 return AMPViewType::GOOGLE_SEARCH_AMP_VIEWER; | 203 return AMPViewType::GOOGLE_SEARCH_AMP_VIEWER; |
152 } | 204 } |
153 | 205 |
154 if (google_hostname_prefix.value() == "news" && | 206 if (google_hostname_prefix.value() == "news" && |
155 url.path_piece() == "/news/amp") { | 207 url.path_piece() == "/news/amp" && !url.query_piece().empty()) { |
156 return AMPViewType::GOOGLE_NEWS_AMP_VIEWER; | 208 return AMPViewType::GOOGLE_NEWS_AMP_VIEWER; |
157 } | 209 } |
158 return AMPViewType::NONE; | 210 return AMPViewType::NONE; |
159 } | 211 } |
OLD | NEW |