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

Unified Diff: chrome/browser/prerender/prerender_manager.cc

Issue 6625066: Add pending preloads indexed by routing id. Start preloading once we navigate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 9 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/prerender/prerender_manager.cc
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index d287698a04a97350fd78f1cd94b7996ba10f5fa2..2a8aa1494a5dc21ef3445e6c76282479dc649a7a 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -63,6 +63,17 @@ struct PrerenderManager::PrerenderContentsData {
}
};
+struct PrerenderManager::PendingContentsData {
+ PendingContentsData(const GURL& url, const std::vector<GURL>& alias_urls,
+ const GURL& referrer)
+ : url_(url), alias_urls_(alias_urls), referrer_(referrer) { }
+ ~PendingContentsData() {}
+ GURL url_;
+ std::vector<GURL> alias_urls_;
+ GURL referrer_;
+};
+
+
PrerenderManager::PrerenderManager(Profile* profile)
: rate_limit_enabled_(true),
profile_(profile),
@@ -95,6 +106,7 @@ bool PrerenderManager::AddPreload(const GURL& url,
DeleteOldEntries();
if (FindEntry(url))
return false;
+
// Do not prerender if there are too many render processes, and we would
// have to use an existing one. We do not want prerendering to happen in
// a shared process, so that we can always reliably lower the CPU
@@ -114,6 +126,7 @@ bool PrerenderManager::AddPreload(const GURL& url,
// this doesn't make sense as the next prerender request will be triggered
// by a navigation and is unlikely to be the same site.
RecordFinalStatus(FINAL_STATUS_RATE_LIMIT_EXCEEDED);
+
return false;
}
@@ -135,6 +148,52 @@ bool PrerenderManager::AddPreload(const GURL& url,
return true;
}
+void PrerenderManager::AddPendingPreload(
+ const std::pair<int,int>& child_route_id_pair,
+ const GURL& url,
+ const std::vector<GURL>& alias_urls,
+ const GURL& referrer) {
+ // Check if this is coming from a valid prerender rvh.
+ bool is_valid_prerender = false;
+ for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin();
+ it != prerender_list_.end(); ++it) {
+ PrerenderContents* pc = it->contents_;
+
+ int child_id;
+ int route_id;
+ bool has_child_id = pc->GetChildId(&child_id);
+ bool has_route_id = has_child_id && pc->GetRouteId(&route_id);
+
+ if (has_child_id && has_route_id &&
+ child_id == child_route_id_pair.first &&
+ route_id == child_route_id_pair.second) {
+ is_valid_prerender = true;
+ break;
+ }
+ }
+
+ // If not, we could check to see if the RenderViewHost specified by the
+ // child_route_id_pair exists and if so just start prerendering, as this
+ // suggests that the link was clicked, though this might prerender something
+ // that the user has already navigated away from. For now, we'll be
+ // conservative and skip the prerender which will mean some prerender requests
+ // from prerendered pages will be missed if the user navigates quickly.
+ if (!is_valid_prerender) {
+ RecordFinalStatus(FINAL_STATUS_PENDING_SKIPPED);
+ return;
+ }
+
+ PendingPrerenderList::iterator it =
+ pending_prerender_list_.find(child_route_id_pair);
+ if (it == pending_prerender_list_.end()) {
+ PendingPrerenderList::value_type el = std::make_pair(child_route_id_pair,
+ std::vector<PendingContentsData>());
+ it = pending_prerender_list_.insert(el).first;
+ }
+
+ it->second.push_back(PendingContentsData(url, alias_urls, referrer));
+}
+
void PrerenderManager::DeleteOldEntries() {
while (!prerender_list_.empty()) {
PrerenderContentsData data = prerender_list_.front();
@@ -185,6 +244,11 @@ bool PrerenderManager::MaybeUsePreloadedPage(TabContents* tc, const GURL& url) {
++prerenders_per_session_count_);
pc->set_final_status(FINAL_STATUS_USED);
+ int child_id;
+ int route_id;
+ CHECK(pc->GetChildId(&child_id));
+ CHECK(pc->GetRouteId(&route_id));
+
RenderViewHost* rvh = pc->render_view_host();
// RenderViewHosts in PrerenderContents start out hidden.
// Since we are actually using it now, restore it.
@@ -194,6 +258,21 @@ bool PrerenderManager::MaybeUsePreloadedPage(TabContents* tc, const GURL& url) {
tc->SwapInRenderViewHost(rvh);
MarkTabContentsAsPrerendered(tc);
+ // See if we have any pending prerender requests for this routing id and start
+ // the preload if we do.
+ std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id);
+ PendingPrerenderList::iterator pending_it =
+ pending_prerender_list_.find(child_route_pair);
+ if (pending_it != pending_prerender_list_.end()) {
+ for (std::vector<PendingContentsData>::iterator content_it =
+ pending_it->second.begin();
+ content_it != pending_it->second.end(); ++content_it) {
+ AddPreload(content_it->url_, content_it->alias_urls_,
+ content_it->referrer_);
+ }
+ pending_prerender_list_.erase(pending_it);
+ }
+
ViewHostMsg_FrameNavigate_Params* p = pc->navigate_params();
if (p != NULL)
tc->DidNavigate(rvh, *p);
@@ -218,6 +297,7 @@ void PrerenderManager::RemoveEntry(PrerenderContents* entry) {
it != prerender_list_.end();
++it) {
if (it->contents_ == entry) {
+ RemovePendingPreload(entry);
prerender_list_.erase(it);
break;
}
@@ -305,6 +385,24 @@ PrerenderContents* PrerenderManager::FindEntry(const GURL& url) {
return NULL;
}
+PrerenderManager::PendingContentsData*
+ PrerenderManager::FindPendingEntry(const GURL& url) {
+ for (PendingPrerenderList::iterator map_it = pending_prerender_list_.begin();
+ map_it != pending_prerender_list_.end();
+ ++map_it) {
+ for (std::vector<PendingContentsData>::iterator content_it =
+ map_it->second.begin();
+ content_it != map_it->second.end();
+ ++content_it) {
+ if (content_it->url_ == url) {
+ return &(*content_it);
+ }
+ }
+ }
+
+ return NULL;
+}
+
// static
void PrerenderManager::RecordPrefetchTagObserved() {
// Ensure that we are in the UI thread, and post to the UI thread if
@@ -331,6 +429,20 @@ void PrerenderManager::RecordPrefetchTagObservedOnUIThread() {
last_prefetch_seen_time_ = base::TimeTicks::Now();
}
+void PrerenderManager::RemovePendingPreload(PrerenderContents* entry) {
+ int child_id;
+ int route_id;
+ bool has_child_id = entry->GetChildId(&child_id);
+ bool has_route_id = has_child_id && entry->GetRouteId(&route_id);
+
+ // If the entry doesn't have a RenderViewHost then it didn't start
+ // prerendering and there shouldn't be any pending preloads to remove.
+ if (has_child_id && has_route_id) {
+ std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id);
+ pending_prerender_list_.erase(child_route_pair);
+ }
+}
+
// static
bool PrerenderManager::ShouldRecordWindowedPPLT() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
« no previous file with comments | « chrome/browser/prerender/prerender_manager.h ('k') | chrome/browser/prerender/prerender_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698