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

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

Issue 2423383002: [Prerender] first contentful paint histograms. (Closed)
Patch Set: comments Created 4 years 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 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 is_redirect, is_no_store); 569 is_redirect, is_no_store);
567 } 570 }
568 571
569 void PrerenderManager::RecordPrefetchRedirectCount(Origin origin, 572 void PrerenderManager::RecordPrefetchRedirectCount(Origin origin,
570 bool is_main_resource, 573 bool is_main_resource,
571 int redirect_count) { 574 int redirect_count) {
572 histograms_->RecordPrefetchRedirectCount(origin, is_main_resource, 575 histograms_->RecordPrefetchRedirectCount(origin, is_main_resource,
573 redirect_count); 576 redirect_count);
574 } 577 }
575 578
576 void PrerenderManager::RecordFirstContentfulPaint(const GURL& url, 579 void PrerenderManager::RecordNoStateFirstContentfulPaint(const GURL& url,
577 bool is_no_store, 580 bool is_no_store,
578 base::TimeDelta time) { 581 bool was_hidden,
579 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30)); 582 base::TimeDelta time) {
583 base::TimeDelta prefetch_age;
584 Origin origin;
585 GetPrefetchInformation(url, &prefetch_age, &origin);
580 586
581 // Compute the prefetch age. 587 histograms_->RecordPrefetchFirstContentfulPaintTime(
588 origin, is_no_store, was_hidden, time, prefetch_age);
589
590 for (auto& observer : observers_) {
591 observer->OnFirstContentfulPaint();
592 }
593 }
594
595 void PrerenderManager::RecordPrerenderFirstContentfulPaint(
596 const GURL& url,
597 content::WebContents* web_contents,
598 bool is_no_store,
599 bool was_hidden,
600 base::TimeTicks first_contentful_paint) {
601 PrerenderTabHelper* tab_helper =
602 PrerenderTabHelper::FromWebContents(web_contents);
603 DCHECK(tab_helper);
604
582 base::TimeDelta prefetch_age; 605 base::TimeDelta prefetch_age;
583 Origin origin = ORIGIN_NONE; 606 // The prefetch origin may not be relevant to the prerender.
584 for (auto it = prefetches_.crbegin(); it != prefetches_.crend(); ++it) { 607 Origin unused_origin;
585 if (it->url == url) { 608 GetPrefetchInformation(url, &prefetch_age, &unused_origin);
586 prefetch_age = GetCurrentTimeTicks() - it->time; 609
587 origin = it->origin; 610 base::TimeTicks swap_ticks = tab_helper->swap_ticks();
588 break; 611 bool fcp_recorded = false;
589 } 612 if (!swap_ticks.is_null() && !first_contentful_paint.is_null()) {
613 histograms_->RecordPrefetchFirstContentfulPaintTime(
614 tab_helper->origin(), is_no_store, was_hidden,
615 first_contentful_paint - swap_ticks, prefetch_age);
616 fcp_recorded = true;
590 } 617 }
618 histograms_->RecordPerceivedFirstContentfulPaintStatus(
619 tab_helper->origin(), fcp_recorded, was_hidden);
pasko 2016/12/22 18:22:01 probably asking it the second time (sorry if so):
mattcary 2016/12/23 09:58:15 Yes, according to Bryan, if a page is hidden then
591 620
592 histograms_->RecordFirstContentfulPaint(origin, is_no_store, time, 621 for (auto& observer : observers_) {
593 prefetch_age); 622 observer->OnFirstContentfulPaint();
594 623 }
595 // Loading a prefetched URL resets the revalidation bypass. Remove the url
596 // from the prefetch list for more accurate metrics.
597 prefetches_.erase(
598 std::remove_if(prefetches_.begin(), prefetches_.end(),
599 [url](const NavigationRecord& r) { return r.url == url; }),
600 prefetches_.end());
601 } 624 }
602 625
603 // static 626 // static
604 PrerenderManager::PrerenderManagerMode PrerenderManager::GetMode() { 627 PrerenderManager::PrerenderManagerMode PrerenderManager::GetMode() {
605 return mode_; 628 return mode_;
606 } 629 }
607 630
608 // static 631 // static
609 void PrerenderManager::SetMode(PrerenderManagerMode mode) { 632 void PrerenderManager::SetMode(PrerenderManagerMode mode) {
610 mode_ = mode; 633 mode_ = mode;
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 base::ElapsedTimer cleanup_timer; 1064 base::ElapsedTimer cleanup_timer;
1042 1065
1043 // Perform deferred cleanup work. 1066 // Perform deferred cleanup work.
1044 DeleteOldWebContents(); 1067 DeleteOldWebContents();
1045 DeleteOldEntries(); 1068 DeleteOldEntries();
1046 if (active_prerenders_.empty()) 1069 if (active_prerenders_.empty())
1047 StopSchedulingPeriodicCleanups(); 1070 StopSchedulingPeriodicCleanups();
1048 1071
1049 to_delete_prerenders_.clear(); 1072 to_delete_prerenders_.clear();
1050 1073
1074 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30));
1075
1051 // Measure how long a the various cleanup tasks took. http://crbug.com/305419. 1076 // Measure how long a the various cleanup tasks took. http://crbug.com/305419.
1052 UMA_HISTOGRAM_TIMES("Prerender.PeriodicCleanupDeleteContentsTime", 1077 UMA_HISTOGRAM_TIMES("Prerender.PeriodicCleanupDeleteContentsTime",
1053 cleanup_timer.Elapsed()); 1078 cleanup_timer.Elapsed());
1054 } 1079 }
1055 1080
1056 void PrerenderManager::PostCleanupTask() { 1081 void PrerenderManager::PostCleanupTask() {
1057 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1082 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1058 base::ThreadTaskRunnerHandle::Get()->PostTask( 1083 base::ThreadTaskRunnerHandle::Get()->PostTask(
1059 FROM_HERE, base::Bind(&PrerenderManager::PeriodicCleanup, 1084 FROM_HERE, base::Bind(&PrerenderManager::PeriodicCleanup,
1060 weak_factory_.GetWeakPtr())); 1085 weak_factory_.GetWeakPtr()));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 void PrerenderManager::SetClockForTesting( 1119 void PrerenderManager::SetClockForTesting(
1095 std::unique_ptr<base::SimpleTestClock> clock) { 1120 std::unique_ptr<base::SimpleTestClock> clock) {
1096 clock_ = std::move(clock); 1121 clock_ = std::move(clock);
1097 } 1122 }
1098 1123
1099 void PrerenderManager::SetTickClockForTesting( 1124 void PrerenderManager::SetTickClockForTesting(
1100 std::unique_ptr<base::SimpleTestTickClock> tick_clock) { 1125 std::unique_ptr<base::SimpleTestTickClock> tick_clock) {
1101 tick_clock_ = std::move(tick_clock); 1126 tick_clock_ = std::move(tick_clock);
1102 } 1127 }
1103 1128
1129 void PrerenderManager::AddObserver(
1130 std::unique_ptr<PrerenderManagerObserver> observer) {
1131 observers_.push_back(std::move(observer));
1132 }
1133
1104 std::unique_ptr<PrerenderContents> PrerenderManager::CreatePrerenderContents( 1134 std::unique_ptr<PrerenderContents> PrerenderManager::CreatePrerenderContents(
1105 const GURL& url, 1135 const GURL& url,
1106 const content::Referrer& referrer, 1136 const content::Referrer& referrer,
1107 Origin origin) { 1137 Origin origin) {
1108 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1138 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1109 return base::WrapUnique(prerender_contents_factory_->CreatePrerenderContents( 1139 return base::WrapUnique(prerender_contents_factory_->CreatePrerenderContents(
1110 this, profile_, url, referrer, origin)); 1140 this, profile_, url, referrer, origin));
1111 } 1141 }
1112 1142
1113 void PrerenderManager::SortActivePrerenders() { 1143 void PrerenderManager::SortActivePrerenders() {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 1186
1157 void PrerenderManager::DeleteOldWebContents() { 1187 void PrerenderManager::DeleteOldWebContents() {
1158 for (WebContents* web_contents : old_web_contents_list_) { 1188 for (WebContents* web_contents : old_web_contents_list_) {
1159 // TODO(dominich): should we use Instant Unload Handler here? 1189 // TODO(dominich): should we use Instant Unload Handler here?
1160 // Or should |old_web_contents_list_| contain unique_ptrs? 1190 // Or should |old_web_contents_list_| contain unique_ptrs?
1161 delete web_contents; 1191 delete web_contents;
1162 } 1192 }
1163 old_web_contents_list_.clear(); 1193 old_web_contents_list_.clear();
1164 } 1194 }
1165 1195
1196 void PrerenderManager::GetPrefetchInformation(const GURL& url,
1197 base::TimeDelta* prefetch_age,
1198 Origin* origin) {
1199 DCHECK(prefetch_age);
1200 DCHECK(origin);
1201 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30));
1202
1203 *prefetch_age = base::TimeDelta();
1204 *origin = ORIGIN_NONE;
1205 for (auto it = prefetches_.crbegin(); it != prefetches_.crend(); ++it) {
1206 if (it->url == url) {
1207 *prefetch_age = GetCurrentTimeTicks() - it->time;
1208 *origin = it->origin;
1209 break;
1210 }
1211 }
1212
1213 // Loading a prefetched URL resets the revalidation bypass. Remove all
1214 // matching urls from the prefetch list for more accurate metrics.
1215 prefetches_.erase(
1216 std::remove_if(prefetches_.begin(), prefetches_.end(),
1217 [url](const NavigationRecord& r) { return r.url == url; }),
1218 prefetches_.end());
1219 }
1220
1166 void PrerenderManager::CleanUpOldNavigations( 1221 void PrerenderManager::CleanUpOldNavigations(
1167 std::vector<NavigationRecord>* navigations, 1222 std::vector<NavigationRecord>* navigations,
1168 base::TimeDelta max_age) { 1223 base::TimeDelta max_age) {
1169 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1224 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1170 1225
1171 // Cutoff. Navigations before this cutoff can be discarded. 1226 // Cutoff. Navigations before this cutoff can be discarded.
1172 base::TimeTicks cutoff = GetCurrentTimeTicks() - max_age; 1227 base::TimeTicks cutoff = GetCurrentTimeTicks() - max_age;
1173 auto it = navigations->begin(); 1228 auto it = navigations->begin();
1174 for (; it != navigations->end(); ++it) { 1229 for (; it != navigations->end(); ++it) {
1175 if (it->time > cutoff) 1230 if (it->time > cutoff)
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 return weak_factory_.GetWeakPtr(); 1425 return weak_factory_.GetWeakPtr();
1371 } 1426 }
1372 1427
1373 void PrerenderManager::SetPrerenderContentsFactoryForTest( 1428 void PrerenderManager::SetPrerenderContentsFactoryForTest(
1374 PrerenderContents::Factory* prerender_contents_factory) { 1429 PrerenderContents::Factory* prerender_contents_factory) {
1375 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1430 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1376 prerender_contents_factory_.reset(prerender_contents_factory); 1431 prerender_contents_factory_.reset(prerender_contents_factory);
1377 } 1432 }
1378 1433
1379 } // namespace prerender 1434 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698