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

Side by Side Diff: chrome/browser/prerender/prerender_manager.cc

Issue 2423383002: [Prerender] first contentful paint histograms. (Closed)
Patch Set: clarify page load metric test Created 3 years, 12 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/prerender/prerender_manager.h" 5 #include "chrome/browser/prerender/prerender_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <functional> 10 #include <functional>
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // |this| is deleted at this point. 150 // |this| is deleted at this point.
151 } 151 }
152 152
153 PrerenderManager* const manager_; 153 PrerenderManager* const manager_;
154 std::unique_ptr<WebContents> tab_; 154 std::unique_ptr<WebContents> tab_;
155 bool suppressed_dialog_; 155 bool suppressed_dialog_;
156 156
157 DISALLOW_COPY_AND_ASSIGN(OnCloseWebContentsDeleter); 157 DISALLOW_COPY_AND_ASSIGN(OnCloseWebContentsDeleter);
158 }; 158 };
159 159
160 PrerenderManagerObserver::~PrerenderManagerObserver() {}
161
160 // static 162 // static
161 int PrerenderManager::prerenders_per_session_count_ = 0; 163 int PrerenderManager::prerenders_per_session_count_ = 0;
162 164
163 // static 165 // static
164 PrerenderManager::PrerenderManagerMode PrerenderManager::mode_ = 166 PrerenderManager::PrerenderManagerMode PrerenderManager::mode_ =
165 PRERENDER_MODE_ENABLED; 167 PRERENDER_MODE_ENABLED;
166 168
167 struct PrerenderManager::NavigationRecord { 169 struct PrerenderManager::NavigationRecord {
168 NavigationRecord(const GURL& url, base::TimeTicks time, Origin origin) 170 NavigationRecord(const GURL& url, base::TimeTicks time, Origin origin)
169 : url(url), time(time), origin(origin) {} 171 : url(url), time(time), origin(origin) {}
170 172
171 GURL url; 173 GURL url;
172 base::TimeTicks time; 174 base::TimeTicks time;
173 Origin origin; 175 Origin origin;
174 }; 176 };
175 177
176 PrerenderManager::PrerenderManager(Profile* profile) 178 PrerenderManager::PrerenderManager(Profile* profile)
177 : profile_(profile), 179 : profile_(profile),
178 prerender_contents_factory_(PrerenderContents::CreateFactory()), 180 prerender_contents_factory_(PrerenderContents::CreateFactory()),
179 prerender_history_(new PrerenderHistory(kHistoryLength)), 181 prerender_history_(new PrerenderHistory(kHistoryLength)),
180 histograms_(new PrerenderHistograms()), 182 histograms_(new PrerenderHistograms()),
181 profile_network_bytes_(0), 183 profile_network_bytes_(0),
182 last_recorded_profile_network_bytes_(0), 184 last_recorded_profile_network_bytes_(0),
183 clock_(new base::DefaultClock()), 185 clock_(new base::DefaultClock()),
184 tick_clock_(new base::DefaultTickClock()), 186 tick_clock_(new base::DefaultTickClock()),
187 page_load_metric_observer_disabled_(false),
185 weak_factory_(this) { 188 weak_factory_(this) {
186 DCHECK_CURRENTLY_ON(BrowserThread::UI); 189 DCHECK_CURRENTLY_ON(BrowserThread::UI);
187 190
188 last_prerender_start_time_ = 191 last_prerender_start_time_ =
189 GetCurrentTimeTicks() - 192 GetCurrentTimeTicks() -
190 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); 193 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs);
191 194
192 notification_registrar_.Add( 195 notification_registrar_.Add(
193 this, chrome::NOTIFICATION_PROFILE_DESTROYED, 196 this, chrome::NOTIFICATION_PROFILE_DESTROYED,
194 content::Source<Profile>(profile_)); 197 content::Source<Profile>(profile_));
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 is_redirect, is_no_store); 561 is_redirect, is_no_store);
559 } 562 }
560 563
561 void PrerenderManager::RecordPrefetchRedirectCount(Origin origin, 564 void PrerenderManager::RecordPrefetchRedirectCount(Origin origin,
562 bool is_main_resource, 565 bool is_main_resource,
563 int redirect_count) { 566 int redirect_count) {
564 histograms_->RecordPrefetchRedirectCount(origin, is_main_resource, 567 histograms_->RecordPrefetchRedirectCount(origin, is_main_resource,
565 redirect_count); 568 redirect_count);
566 } 569 }
567 570
568 void PrerenderManager::RecordFirstContentfulPaint(const GURL& url, 571 void PrerenderManager::RecordNoStateFirstContentfulPaint(const GURL& url,
569 bool is_no_store, 572 bool is_no_store,
570 base::TimeDelta time) { 573 bool was_hidden,
571 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30)); 574 base::TimeDelta time) {
575 base::TimeDelta prefetch_age;
576 Origin origin;
577 GetPrefetchInformation(url, &prefetch_age, &origin);
572 578
573 // Compute the prefetch age. 579 histograms_->RecordPrefetchFirstContentfulPaintTime(
580 origin, is_no_store, was_hidden, time, prefetch_age);
581
582 for (auto& observer : observers_) {
583 observer->OnFirstContentfulPaint();
584 }
585 }
586
587 void PrerenderManager::RecordPrerenderFirstContentfulPaint(
588 const GURL& url,
589 content::WebContents* web_contents,
590 bool is_no_store,
591 bool was_hidden,
592 base::TimeTicks first_contentful_paint) {
593 DCHECK(!first_contentful_paint.is_null());
594
595 PrerenderTabHelper* tab_helper =
596 PrerenderTabHelper::FromWebContents(web_contents);
597 DCHECK(tab_helper);
598
574 base::TimeDelta prefetch_age; 599 base::TimeDelta prefetch_age;
575 Origin origin = ORIGIN_NONE; 600 // The origin at prefetch is superceeded by the tab_helper origin for the
576 for (auto it = prefetches_.crbegin(); it != prefetches_.crend(); ++it) { 601 // histogram recording, below.
577 if (it->url == url) { 602 Origin unused_origin;
578 prefetch_age = GetCurrentTimeTicks() - it->time; 603 GetPrefetchInformation(url, &prefetch_age, &unused_origin);
579 origin = it->origin; 604
580 break; 605 base::TimeTicks swap_ticks = tab_helper->swap_ticks();
581 } 606 bool fcp_recorded = false;
607 if (!swap_ticks.is_null() && !first_contentful_paint.is_null()) {
608 histograms_->RecordPrefetchFirstContentfulPaintTime(
609 tab_helper->origin(), is_no_store, was_hidden,
610 first_contentful_paint - swap_ticks, prefetch_age);
611 fcp_recorded = true;
582 } 612 }
613 histograms_->RecordPerceivedFirstContentfulPaintStatus(
614 tab_helper->origin(), fcp_recorded, was_hidden);
583 615
584 histograms_->RecordFirstContentfulPaint(origin, is_no_store, time, 616 for (auto& observer : observers_) {
585 prefetch_age); 617 observer->OnFirstContentfulPaint();
586 618 }
587 // Loading a prefetched URL resets the revalidation bypass. Remove the url
588 // from the prefetch list for more accurate metrics.
589 prefetches_.erase(
590 std::remove_if(prefetches_.begin(), prefetches_.end(),
591 [url](const NavigationRecord& r) { return r.url == url; }),
592 prefetches_.end());
593 } 619 }
594 620
595 // static 621 // static
596 PrerenderManager::PrerenderManagerMode PrerenderManager::GetMode() { 622 PrerenderManager::PrerenderManagerMode PrerenderManager::GetMode() {
597 return mode_; 623 return mode_;
598 } 624 }
599 625
600 // static 626 // static
601 void PrerenderManager::SetMode(PrerenderManagerMode mode) { 627 void PrerenderManager::SetMode(PrerenderManagerMode mode) {
602 mode_ = mode; 628 mode_ = mode;
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 base::ElapsedTimer cleanup_timer; 1059 base::ElapsedTimer cleanup_timer;
1034 1060
1035 // Perform deferred cleanup work. 1061 // Perform deferred cleanup work.
1036 DeleteOldWebContents(); 1062 DeleteOldWebContents();
1037 DeleteOldEntries(); 1063 DeleteOldEntries();
1038 if (active_prerenders_.empty()) 1064 if (active_prerenders_.empty())
1039 StopSchedulingPeriodicCleanups(); 1065 StopSchedulingPeriodicCleanups();
1040 1066
1041 to_delete_prerenders_.clear(); 1067 to_delete_prerenders_.clear();
1042 1068
1069 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30));
1070
1043 // Measure how long a the various cleanup tasks took. http://crbug.com/305419. 1071 // Measure how long a the various cleanup tasks took. http://crbug.com/305419.
1044 UMA_HISTOGRAM_TIMES("Prerender.PeriodicCleanupDeleteContentsTime", 1072 UMA_HISTOGRAM_TIMES("Prerender.PeriodicCleanupDeleteContentsTime",
1045 cleanup_timer.Elapsed()); 1073 cleanup_timer.Elapsed());
1046 } 1074 }
1047 1075
1048 void PrerenderManager::PostCleanupTask() { 1076 void PrerenderManager::PostCleanupTask() {
1049 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1077 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1050 base::ThreadTaskRunnerHandle::Get()->PostTask( 1078 base::ThreadTaskRunnerHandle::Get()->PostTask(
1051 FROM_HERE, base::Bind(&PrerenderManager::PeriodicCleanup, 1079 FROM_HERE, base::Bind(&PrerenderManager::PeriodicCleanup,
1052 weak_factory_.GetWeakPtr())); 1080 weak_factory_.GetWeakPtr()));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 void PrerenderManager::SetClockForTesting( 1114 void PrerenderManager::SetClockForTesting(
1087 std::unique_ptr<base::SimpleTestClock> clock) { 1115 std::unique_ptr<base::SimpleTestClock> clock) {
1088 clock_ = std::move(clock); 1116 clock_ = std::move(clock);
1089 } 1117 }
1090 1118
1091 void PrerenderManager::SetTickClockForTesting( 1119 void PrerenderManager::SetTickClockForTesting(
1092 std::unique_ptr<base::SimpleTestTickClock> tick_clock) { 1120 std::unique_ptr<base::SimpleTestTickClock> tick_clock) {
1093 tick_clock_ = std::move(tick_clock); 1121 tick_clock_ = std::move(tick_clock);
1094 } 1122 }
1095 1123
1124 void PrerenderManager::AddObserver(
1125 std::unique_ptr<PrerenderManagerObserver> observer) {
1126 observers_.push_back(std::move(observer));
1127 }
1128
1096 std::unique_ptr<PrerenderContents> PrerenderManager::CreatePrerenderContents( 1129 std::unique_ptr<PrerenderContents> PrerenderManager::CreatePrerenderContents(
1097 const GURL& url, 1130 const GURL& url,
1098 const content::Referrer& referrer, 1131 const content::Referrer& referrer,
1099 Origin origin) { 1132 Origin origin) {
1100 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1133 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1101 return base::WrapUnique(prerender_contents_factory_->CreatePrerenderContents( 1134 return base::WrapUnique(prerender_contents_factory_->CreatePrerenderContents(
1102 this, profile_, url, referrer, origin)); 1135 this, profile_, url, referrer, origin));
1103 } 1136 }
1104 1137
1105 void PrerenderManager::SortActivePrerenders() { 1138 void PrerenderManager::SortActivePrerenders() {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 1181
1149 void PrerenderManager::DeleteOldWebContents() { 1182 void PrerenderManager::DeleteOldWebContents() {
1150 for (WebContents* web_contents : old_web_contents_list_) { 1183 for (WebContents* web_contents : old_web_contents_list_) {
1151 // TODO(dominich): should we use Instant Unload Handler here? 1184 // TODO(dominich): should we use Instant Unload Handler here?
1152 // Or should |old_web_contents_list_| contain unique_ptrs? 1185 // Or should |old_web_contents_list_| contain unique_ptrs?
1153 delete web_contents; 1186 delete web_contents;
1154 } 1187 }
1155 old_web_contents_list_.clear(); 1188 old_web_contents_list_.clear();
1156 } 1189 }
1157 1190
1191 void PrerenderManager::GetPrefetchInformation(const GURL& url,
1192 base::TimeDelta* prefetch_age,
1193 Origin* origin) {
1194 DCHECK(prefetch_age);
1195 DCHECK(origin);
1196 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30));
1197
1198 *prefetch_age = base::TimeDelta();
1199 *origin = ORIGIN_NONE;
1200 for (auto it = prefetches_.crbegin(); it != prefetches_.crend(); ++it) {
1201 if (it->url == url) {
1202 *prefetch_age = GetCurrentTimeTicks() - it->time;
1203 *origin = it->origin;
1204 break;
1205 }
1206 }
1207
1208 // Loading a prefetched URL resets the revalidation bypass. Remove all
1209 // matching urls from the prefetch list for more accurate metrics.
1210 prefetches_.erase(
1211 std::remove_if(prefetches_.begin(), prefetches_.end(),
1212 [url](const NavigationRecord& r) { return r.url == url; }),
1213 prefetches_.end());
1214 }
1215
1158 void PrerenderManager::CleanUpOldNavigations( 1216 void PrerenderManager::CleanUpOldNavigations(
1159 std::vector<NavigationRecord>* navigations, 1217 std::vector<NavigationRecord>* navigations,
1160 base::TimeDelta max_age) { 1218 base::TimeDelta max_age) {
1161 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1219 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1162 1220
1163 // Cutoff. Navigations before this cutoff can be discarded. 1221 // Cutoff. Navigations before this cutoff can be discarded.
1164 base::TimeTicks cutoff = GetCurrentTimeTicks() - max_age; 1222 base::TimeTicks cutoff = GetCurrentTimeTicks() - max_age;
1165 auto it = navigations->begin(); 1223 auto it = navigations->begin();
1166 for (; it != navigations->end(); ++it) { 1224 for (; it != navigations->end(); ++it) {
1167 if (it->time > cutoff) 1225 if (it->time > cutoff)
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1362 return weak_factory_.GetWeakPtr(); 1420 return weak_factory_.GetWeakPtr();
1363 } 1421 }
1364 1422
1365 void PrerenderManager::SetPrerenderContentsFactoryForTest( 1423 void PrerenderManager::SetPrerenderContentsFactoryForTest(
1366 PrerenderContents::Factory* prerender_contents_factory) { 1424 PrerenderContents::Factory* prerender_contents_factory) {
1367 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1425 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1368 prerender_contents_factory_.reset(prerender_contents_factory); 1426 prerender_contents_factory_.reset(prerender_contents_factory);
1369 } 1427 }
1370 1428
1371 } // namespace prerender 1429 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698