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

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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // |this| is deleted at this point. 143 // |this| is deleted at this point.
144 } 144 }
145 145
146 PrerenderManager* const manager_; 146 PrerenderManager* const manager_;
147 std::unique_ptr<WebContents> tab_; 147 std::unique_ptr<WebContents> tab_;
148 bool suppressed_dialog_; 148 bool suppressed_dialog_;
149 149
150 DISALLOW_COPY_AND_ASSIGN(OnCloseWebContentsDeleter); 150 DISALLOW_COPY_AND_ASSIGN(OnCloseWebContentsDeleter);
151 }; 151 };
152 152
153 PrerenderManagerObserver::~PrerenderManagerObserver() {}
154
153 // static 155 // static
154 int PrerenderManager::prerenders_per_session_count_ = 0; 156 int PrerenderManager::prerenders_per_session_count_ = 0;
155 157
156 // static 158 // static
157 PrerenderManager::PrerenderManagerMode PrerenderManager::mode_ = 159 PrerenderManager::PrerenderManagerMode PrerenderManager::mode_ =
158 PRERENDER_MODE_ENABLED; 160 PRERENDER_MODE_ENABLED;
159 161
160 struct PrerenderManager::NavigationRecord { 162 struct PrerenderManager::NavigationRecord {
161 NavigationRecord(const GURL& url, base::TimeTicks time, Origin origin) 163 NavigationRecord(const GURL& url, base::TimeTicks time, Origin origin)
162 : url(url), time(time), origin(origin) {} 164 : url(url), time(time), origin(origin) {}
163 165
164 GURL url; 166 GURL url;
165 base::TimeTicks time; 167 base::TimeTicks time;
166 Origin origin; 168 Origin origin;
167 }; 169 };
168 170
169 PrerenderManager::PrerenderManager(Profile* profile) 171 PrerenderManager::PrerenderManager(Profile* profile)
170 : profile_(profile), 172 : profile_(profile),
171 prerender_contents_factory_(PrerenderContents::CreateFactory()), 173 prerender_contents_factory_(PrerenderContents::CreateFactory()),
172 prerender_history_(new PrerenderHistory(kHistoryLength)), 174 prerender_history_(new PrerenderHistory(kHistoryLength)),
173 histograms_(new PrerenderHistograms()), 175 histograms_(new PrerenderHistograms()),
174 profile_network_bytes_(0), 176 profile_network_bytes_(0),
175 last_recorded_profile_network_bytes_(0), 177 last_recorded_profile_network_bytes_(0),
176 clock_(new base::DefaultClock()), 178 clock_(new base::DefaultClock()),
177 tick_clock_(new base::DefaultTickClock()), 179 tick_clock_(new base::DefaultTickClock()),
180 page_load_metric_observer_disabled_(false),
178 weak_factory_(this) { 181 weak_factory_(this) {
179 DCHECK_CURRENTLY_ON(BrowserThread::UI); 182 DCHECK_CURRENTLY_ON(BrowserThread::UI);
180 183
181 last_prerender_start_time_ = 184 last_prerender_start_time_ =
182 GetCurrentTimeTicks() - 185 GetCurrentTimeTicks() -
183 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); 186 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs);
184 187
185 notification_registrar_.Add( 188 notification_registrar_.Add(
186 this, chrome::NOTIFICATION_PROFILE_DESTROYED, 189 this, chrome::NOTIFICATION_PROFILE_DESTROYED,
187 content::Source<Profile>(profile_)); 190 content::Source<Profile>(profile_));
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 is_redirect, is_no_store); 562 is_redirect, is_no_store);
560 } 563 }
561 564
562 void PrerenderManager::RecordPrefetchRedirectCount(Origin origin, 565 void PrerenderManager::RecordPrefetchRedirectCount(Origin origin,
563 bool is_main_resource, 566 bool is_main_resource,
564 int redirect_count) { 567 int redirect_count) {
565 histograms_->RecordPrefetchRedirectCount(origin, is_main_resource, 568 histograms_->RecordPrefetchRedirectCount(origin, is_main_resource,
566 redirect_count); 569 redirect_count);
567 } 570 }
568 571
569 void PrerenderManager::RecordFirstContentfulPaint(const GURL& url, 572 void PrerenderManager::RecordNoStateFirstContentfulPaint(const GURL& url,
570 bool is_no_store, 573 bool is_no_store,
571 base::TimeDelta time) { 574 bool was_hidden,
572 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30)); 575 base::TimeDelta time) {
576 base::TimeDelta prefetch_age;
577 Origin origin;
578 GetPrefetchInformation(url, &prefetch_age, &origin);
573 579
574 // Compute the prefetch age. 580 histograms_->RecordPrefetchFirstContentfulPaintTime(
581 origin, is_no_store, was_hidden, time, prefetch_age);
582
583 for (auto& observer : observers_) {
584 observer->OnFirstContentfulPaint();
585 }
586 }
587
588 void PrerenderManager::RecordPrerenderFirstContentfulPaint(
589 const GURL& url,
590 content::WebContents* web_contents,
591 bool is_no_store,
592 bool was_hidden,
593 base::TimeTicks first_contentful_paint) {
594 PrerenderTabHelper* tab_helper =
595 PrerenderTabHelper::FromWebContents(web_contents);
596 DCHECK(tab_helper);
597
575 base::TimeDelta prefetch_age; 598 base::TimeDelta prefetch_age;
576 Origin origin = ORIGIN_NONE; 599 // The prefetch origin may not be relevant to the prerender.
pasko 2016/12/21 18:39:09 s/may not be/is not/
mattcary 2016/12/22 10:49:07 No, may not be. Sometimes it is the same.
pasko 2016/12/22 18:22:00 Then extracting this bit of information from the c
mattcary 2016/12/23 09:58:15 Oh, I see. Done.
577 for (auto it = prefetches_.crbegin(); it != prefetches_.crend(); ++it) { 600 Origin unused_origin;
578 if (it->url == url) { 601 GetPrefetchInformation(url, &prefetch_age, &unused_origin);
579 prefetch_age = GetCurrentTimeTicks() - it->time; 602
580 origin = it->origin; 603 base::TimeTicks last_swap = tab_helper->last_swap();
581 break; 604 if (!last_swap.is_null() && !first_contentful_paint.is_null()) {
582 } 605 histograms_->RecordPrefetchFirstContentfulPaintTime(
606 tab_helper->origin(), is_no_store, was_hidden,
607 first_contentful_paint - last_swap, prefetch_age);
608 histograms_->RecordPerceivedFirstContentfulPaintStatus(tab_helper->origin(),
609 true, was_hidden);
610 } else {
611 histograms_->RecordPerceivedFirstContentfulPaintStatus(tab_helper->origin(),
612 false, was_hidden);
pasko 2016/12/21 18:39:09 this repetition with changing one magic boolean ca
mattcary 2016/12/22 10:49:07 Done.
583 } 613 }
584 614
585 histograms_->RecordFirstContentfulPaint(origin, is_no_store, time, 615 for (auto& observer : observers_) {
586 prefetch_age); 616 observer->OnFirstContentfulPaint();
587 617 }
588 // Loading a prefetched URL resets the revalidation bypass. Remove the url
589 // from the prefetch list for more accurate metrics.
590 prefetches_.erase(
591 std::remove_if(prefetches_.begin(), prefetches_.end(),
592 [url](const NavigationRecord& r) { return r.url == url; }),
593 prefetches_.end());
594 } 618 }
595 619
596 // static 620 // static
597 PrerenderManager::PrerenderManagerMode PrerenderManager::GetMode() { 621 PrerenderManager::PrerenderManagerMode PrerenderManager::GetMode() {
598 return mode_; 622 return mode_;
599 } 623 }
600 624
601 // static 625 // static
602 void PrerenderManager::SetMode(PrerenderManagerMode mode) { 626 void PrerenderManager::SetMode(PrerenderManagerMode mode) {
603 mode_ = mode; 627 mode_ = mode;
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 base::ElapsedTimer cleanup_timer; 1056 base::ElapsedTimer cleanup_timer;
1033 1057
1034 // Perform deferred cleanup work. 1058 // Perform deferred cleanup work.
1035 DeleteOldWebContents(); 1059 DeleteOldWebContents();
1036 DeleteOldEntries(); 1060 DeleteOldEntries();
1037 if (active_prerenders_.empty()) 1061 if (active_prerenders_.empty())
1038 StopSchedulingPeriodicCleanups(); 1062 StopSchedulingPeriodicCleanups();
1039 1063
1040 to_delete_prerenders_.clear(); 1064 to_delete_prerenders_.clear();
1041 1065
1066 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30));
1067
1042 // Measure how long a the various cleanup tasks took. http://crbug.com/305419. 1068 // Measure how long a the various cleanup tasks took. http://crbug.com/305419.
1043 UMA_HISTOGRAM_TIMES("Prerender.PeriodicCleanupDeleteContentsTime", 1069 UMA_HISTOGRAM_TIMES("Prerender.PeriodicCleanupDeleteContentsTime",
1044 cleanup_timer.Elapsed()); 1070 cleanup_timer.Elapsed());
1045 } 1071 }
1046 1072
1047 void PrerenderManager::PostCleanupTask() { 1073 void PrerenderManager::PostCleanupTask() {
1048 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1074 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1049 base::ThreadTaskRunnerHandle::Get()->PostTask( 1075 base::ThreadTaskRunnerHandle::Get()->PostTask(
1050 FROM_HERE, base::Bind(&PrerenderManager::PeriodicCleanup, 1076 FROM_HERE, base::Bind(&PrerenderManager::PeriodicCleanup,
1051 weak_factory_.GetWeakPtr())); 1077 weak_factory_.GetWeakPtr()));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 void PrerenderManager::SetClockForTesting( 1111 void PrerenderManager::SetClockForTesting(
1086 std::unique_ptr<base::SimpleTestClock> clock) { 1112 std::unique_ptr<base::SimpleTestClock> clock) {
1087 clock_ = std::move(clock); 1113 clock_ = std::move(clock);
1088 } 1114 }
1089 1115
1090 void PrerenderManager::SetTickClockForTesting( 1116 void PrerenderManager::SetTickClockForTesting(
1091 std::unique_ptr<base::SimpleTestTickClock> tick_clock) { 1117 std::unique_ptr<base::SimpleTestTickClock> tick_clock) {
1092 tick_clock_ = std::move(tick_clock); 1118 tick_clock_ = std::move(tick_clock);
1093 } 1119 }
1094 1120
1121 void PrerenderManager::AddObserver(
1122 std::unique_ptr<PrerenderManagerObserver> observer) {
1123 observers_.push_back(std::move(observer));
1124 }
1125
1095 std::unique_ptr<PrerenderContents> PrerenderManager::CreatePrerenderContents( 1126 std::unique_ptr<PrerenderContents> PrerenderManager::CreatePrerenderContents(
1096 const GURL& url, 1127 const GURL& url,
1097 const content::Referrer& referrer, 1128 const content::Referrer& referrer,
1098 Origin origin) { 1129 Origin origin) {
1099 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1130 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1100 return base::WrapUnique(prerender_contents_factory_->CreatePrerenderContents( 1131 return base::WrapUnique(prerender_contents_factory_->CreatePrerenderContents(
1101 this, profile_, url, referrer, origin)); 1132 this, profile_, url, referrer, origin));
1102 } 1133 }
1103 1134
1104 void PrerenderManager::SortActivePrerenders() { 1135 void PrerenderManager::SortActivePrerenders() {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 1178
1148 void PrerenderManager::DeleteOldWebContents() { 1179 void PrerenderManager::DeleteOldWebContents() {
1149 for (WebContents* web_contents : old_web_contents_list_) { 1180 for (WebContents* web_contents : old_web_contents_list_) {
1150 // TODO(dominich): should we use Instant Unload Handler here? 1181 // TODO(dominich): should we use Instant Unload Handler here?
1151 // Or should |old_web_contents_list_| contain unique_ptrs? 1182 // Or should |old_web_contents_list_| contain unique_ptrs?
1152 delete web_contents; 1183 delete web_contents;
1153 } 1184 }
1154 old_web_contents_list_.clear(); 1185 old_web_contents_list_.clear();
1155 } 1186 }
1156 1187
1188 void PrerenderManager::GetPrefetchInformation(const GURL& url,
1189 base::TimeDelta* prefetch_age,
1190 Origin* origin) {
1191 DCHECK(prefetch_age);
1192 DCHECK(origin);
1193 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30));
1194
1195 *prefetch_age = base::TimeDelta();
1196 *origin = ORIGIN_NONE;
1197 for (auto it = prefetches_.crbegin(); it != prefetches_.crend(); ++it) {
1198 if (it->url == url) {
1199 *prefetch_age = GetCurrentTimeTicks() - it->time;
1200 *origin = it->origin;
1201 break;
1202 }
1203 }
1204
1205 // Loading a prefetched URL resets the revalidation bypass. Remove all
1206 // matching urls from the prefetch list for more accurate metrics.
1207 prefetches_.erase(
1208 std::remove_if(prefetches_.begin(), prefetches_.end(),
1209 [url](const NavigationRecord& r) { return r.url == url; }),
1210 prefetches_.end());
1211 }
1212
1157 void PrerenderManager::CleanUpOldNavigations( 1213 void PrerenderManager::CleanUpOldNavigations(
1158 std::vector<NavigationRecord>* navigations, 1214 std::vector<NavigationRecord>* navigations,
1159 base::TimeDelta max_age) { 1215 base::TimeDelta max_age) {
1160 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1216 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1161 1217
1162 // Cutoff. Navigations before this cutoff can be discarded. 1218 // Cutoff. Navigations before this cutoff can be discarded.
1163 base::TimeTicks cutoff = GetCurrentTimeTicks() - max_age; 1219 base::TimeTicks cutoff = GetCurrentTimeTicks() - max_age;
1164 auto it = navigations->begin(); 1220 auto it = navigations->begin();
1165 for (; it != navigations->end(); ++it) { 1221 for (; it != navigations->end(); ++it) {
1166 if (it->time > cutoff) 1222 if (it->time > cutoff)
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 return weak_factory_.GetWeakPtr(); 1417 return weak_factory_.GetWeakPtr();
1362 } 1418 }
1363 1419
1364 void PrerenderManager::SetPrerenderContentsFactoryForTest( 1420 void PrerenderManager::SetPrerenderContentsFactoryForTest(
1365 PrerenderContents::Factory* prerender_contents_factory) { 1421 PrerenderContents::Factory* prerender_contents_factory) {
1366 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1422 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1367 prerender_contents_factory_.reset(prerender_contents_factory); 1423 prerender_contents_factory_.reset(prerender_contents_factory);
1368 } 1424 }
1369 1425
1370 } // namespace prerender 1426 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698