Chromium Code Reviews| 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 committed_url_ = navigation_handle->GetURL(); |
| 75 return (view_type_ != AMPViewType::NONE) ? CONTINUE_OBSERVING | 87 view_type_ = GetAMPViewType(committed_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 == last_same_document_url_) | |
| 97 return; | |
| 98 last_same_document_url_ = url; | |
| 99 | |
| 100 // Ignore same document navigations that go to the committed URL, as they are | |
| 101 // unlikely to be real navigations to new content. | |
| 102 if (url == committed_url_) | |
|
RyanSturm
2017/05/16 22:32:10
IIUC, this check seems odd. Specifically, if a use
Bryan McQuade
2017/05/17 12:38:34
Yeah, you're right - we want to ignore nav updates
| |
| 103 return; | |
| 104 | |
| 105 AMPViewType same_document_view_type = GetAMPViewType(url); | |
| 106 if (same_document_view_type == AMPViewType::NONE) | |
| 107 return; | |
| 108 | |
| 109 // Though we're not currently able to track page load metrics such as FCP for | |
| 110 // same-document navigations, we can count how often they happen, to better | |
| 111 // understand the relative frequency of same-document vs new-document AMP | |
| 112 // navigations. | |
| 113 UMA_HISTOGRAM_ENUMERATION( | |
| 114 std::string(kHistogramPrefix).append("SameDocumentView"), | |
| 115 same_document_view_type, AMPViewType::AMP_VIEW_TYPE_LAST); | |
| 77 } | 116 } |
| 78 | 117 |
| 79 void AMPPageLoadMetricsObserver::OnDomContentLoadedEventStart( | 118 void AMPPageLoadMetricsObserver::OnDomContentLoadedEventStart( |
| 80 const page_load_metrics::PageLoadTiming& timing, | 119 const page_load_metrics::PageLoadTiming& timing, |
| 81 const page_load_metrics::PageLoadExtraInfo& info) { | 120 const page_load_metrics::PageLoadExtraInfo& info) { |
| 121 if (view_type_ == AMPViewType::NONE) | |
| 122 return; | |
| 123 | |
| 82 if (!WasStartedInForegroundOptionalEventInForeground( | 124 if (!WasStartedInForegroundOptionalEventInForeground( |
| 83 timing.document_timing.dom_content_loaded_event_start, info)) { | 125 timing.document_timing.dom_content_loaded_event_start, info)) { |
| 84 return; | 126 return; |
| 85 } | 127 } |
| 86 RECORD_HISTOGRAM_FOR_TYPE( | 128 RECORD_HISTOGRAM_FOR_TYPE( |
| 87 kHistogramAMPDOMContentLoadedEventFired, view_type_, | 129 kHistogramAMPDOMContentLoadedEventFired, view_type_, |
| 88 timing.document_timing.dom_content_loaded_event_start.value()); | 130 timing.document_timing.dom_content_loaded_event_start.value()); |
| 89 } | 131 } |
| 90 | 132 |
| 91 void AMPPageLoadMetricsObserver::OnLoadEventStart( | 133 void AMPPageLoadMetricsObserver::OnLoadEventStart( |
| 92 const page_load_metrics::PageLoadTiming& timing, | 134 const page_load_metrics::PageLoadTiming& timing, |
| 93 const page_load_metrics::PageLoadExtraInfo& info) { | 135 const page_load_metrics::PageLoadExtraInfo& info) { |
| 136 if (view_type_ == AMPViewType::NONE) | |
| 137 return; | |
| 138 | |
| 94 if (!WasStartedInForegroundOptionalEventInForeground( | 139 if (!WasStartedInForegroundOptionalEventInForeground( |
| 95 timing.document_timing.load_event_start, info)) { | 140 timing.document_timing.load_event_start, info)) { |
| 96 return; | 141 return; |
| 97 } | 142 } |
| 98 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPLoadEventFired, view_type_, | 143 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPLoadEventFired, view_type_, |
| 99 timing.document_timing.load_event_start.value()); | 144 timing.document_timing.load_event_start.value()); |
| 100 } | 145 } |
| 101 | 146 |
| 102 void AMPPageLoadMetricsObserver::OnFirstLayout( | 147 void AMPPageLoadMetricsObserver::OnFirstLayout( |
| 103 const page_load_metrics::PageLoadTiming& timing, | 148 const page_load_metrics::PageLoadTiming& timing, |
| 104 const page_load_metrics::PageLoadExtraInfo& info) { | 149 const page_load_metrics::PageLoadExtraInfo& info) { |
| 150 if (view_type_ == AMPViewType::NONE) | |
| 151 return; | |
| 152 | |
| 105 if (!WasStartedInForegroundOptionalEventInForeground( | 153 if (!WasStartedInForegroundOptionalEventInForeground( |
| 106 timing.document_timing.first_layout, info)) { | 154 timing.document_timing.first_layout, info)) { |
| 107 return; | 155 return; |
| 108 } | 156 } |
| 109 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPFirstLayout, view_type_, | 157 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPFirstLayout, view_type_, |
| 110 timing.document_timing.first_layout.value()); | 158 timing.document_timing.first_layout.value()); |
| 111 } | 159 } |
| 112 | 160 |
| 113 void AMPPageLoadMetricsObserver::OnFirstContentfulPaintInPage( | 161 void AMPPageLoadMetricsObserver::OnFirstContentfulPaintInPage( |
| 114 const page_load_metrics::PageLoadTiming& timing, | 162 const page_load_metrics::PageLoadTiming& timing, |
| 115 const page_load_metrics::PageLoadExtraInfo& info) { | 163 const page_load_metrics::PageLoadExtraInfo& info) { |
| 164 if (view_type_ == AMPViewType::NONE) | |
| 165 return; | |
| 166 | |
| 116 if (!WasStartedInForegroundOptionalEventInForeground( | 167 if (!WasStartedInForegroundOptionalEventInForeground( |
| 117 timing.paint_timing.first_contentful_paint, info)) { | 168 timing.paint_timing.first_contentful_paint, info)) { |
| 118 return; | 169 return; |
| 119 } | 170 } |
| 120 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPFirstContentfulPaint, view_type_, | 171 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPFirstContentfulPaint, view_type_, |
| 121 timing.paint_timing.first_contentful_paint.value()); | 172 timing.paint_timing.first_contentful_paint.value()); |
| 122 } | 173 } |
| 123 | 174 |
| 124 void AMPPageLoadMetricsObserver::OnParseStart( | 175 void AMPPageLoadMetricsObserver::OnParseStart( |
| 125 const page_load_metrics::PageLoadTiming& timing, | 176 const page_load_metrics::PageLoadTiming& timing, |
| 126 const page_load_metrics::PageLoadExtraInfo& info) { | 177 const page_load_metrics::PageLoadExtraInfo& info) { |
| 178 if (view_type_ == AMPViewType::NONE) | |
| 179 return; | |
| 180 | |
| 127 if (!WasStartedInForegroundOptionalEventInForeground( | 181 if (!WasStartedInForegroundOptionalEventInForeground( |
| 128 timing.parse_timing.parse_start, info)) { | 182 timing.parse_timing.parse_start, info)) { |
| 129 return; | 183 return; |
| 130 } | 184 } |
| 131 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPParseStart, view_type_, | 185 RECORD_HISTOGRAM_FOR_TYPE(kHistogramAMPParseStart, view_type_, |
| 132 timing.parse_timing.parse_start.value()); | 186 timing.parse_timing.parse_start.value()); |
| 133 } | 187 } |
| 134 | 188 |
| 135 // static | 189 // static |
| 136 AMPPageLoadMetricsObserver::AMPViewType | 190 AMPPageLoadMetricsObserver::AMPViewType |
| 137 AMPPageLoadMetricsObserver::GetAMPViewType(const GURL& url) { | 191 AMPPageLoadMetricsObserver::GetAMPViewType(const GURL& url) { |
| 138 if (base::EndsWith(url.host(), kAmpCacheHostSuffix, | 192 if (base::EndsWith(url.host(), kAmpCacheHostSuffix, |
| 139 base::CompareCase::INSENSITIVE_ASCII)) { | 193 base::CompareCase::INSENSITIVE_ASCII)) { |
| 140 return AMPViewType::AMP_CACHE; | 194 return AMPViewType::AMP_CACHE; |
| 141 } | 195 } |
| 142 | 196 |
| 143 base::Optional<std::string> google_hostname_prefix = | 197 base::Optional<std::string> google_hostname_prefix = |
| 144 page_load_metrics::GetGoogleHostnamePrefix(url); | 198 page_load_metrics::GetGoogleHostnamePrefix(url); |
| 145 if (!google_hostname_prefix.has_value()) | 199 if (!google_hostname_prefix.has_value()) |
| 146 return AMPViewType::NONE; | 200 return AMPViewType::NONE; |
| 147 | 201 |
| 148 if (google_hostname_prefix.value() == "www" && | 202 if (google_hostname_prefix.value() == "www" && |
| 149 base::StartsWith(url.path_piece(), "/amp/", | 203 base::StartsWith(url.path_piece(), "/amp/", |
| 150 base::CompareCase::SENSITIVE)) { | 204 base::CompareCase::SENSITIVE)) { |
| 151 return AMPViewType::GOOGLE_SEARCH_AMP_VIEWER; | 205 return AMPViewType::GOOGLE_SEARCH_AMP_VIEWER; |
| 152 } | 206 } |
| 153 | 207 |
| 154 if (google_hostname_prefix.value() == "news" && | 208 if (google_hostname_prefix.value() == "news" && |
| 155 url.path_piece() == "/news/amp") { | 209 url.path_piece() == "/news/amp" && !url.query_piece().empty()) { |
| 156 return AMPViewType::GOOGLE_NEWS_AMP_VIEWER; | 210 return AMPViewType::GOOGLE_NEWS_AMP_VIEWER; |
| 157 } | 211 } |
| 158 return AMPViewType::NONE; | 212 return AMPViewType::NONE; |
| 159 } | 213 } |
| OLD | NEW |