diff options
author | mmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-30 00:41:44 +0000 |
---|---|---|
committer | mmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-30 00:41:44 +0000 |
commit | 16e923d415597f97b567c5d3870ad4d489c3e31b (patch) | |
tree | 4daa203932464fb01cf4bdb116d6fd596eacdd96 /chrome/renderer/prerender | |
parent | bcf09fc7ff33c6bd4058f515baa5ab3133f355ec (diff) | |
download | chromium_src-16e923d415597f97b567c5d3870ad4d489c3e31b.zip chromium_src-16e923d415597f97b567c5d3870ad4d489c3e31b.tar.gz chromium_src-16e923d415597f97b567c5d3870ad4d489c3e31b.tar.bz2 |
Remove most prerendering code/references from content.
The only place where prerendering code remains in content
is in ResourceDispatcherHost.
As NavigationState can no longer be used to track
prerendering histogram information, the prerendering
renderer-side histograms have been reworked (And
renamed) as well.
The histogram intended to track use of
prerendering RenderViews has been removed, as
histograms are not recorded when a RenderView is
destroyed.
BUG=77090
TEST=Compiles, existing PrerenderBrowserTests, grep
Review URL: http://codereview.chromium.org/6900026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83642 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/prerender')
-rw-r--r-- | chrome/renderer/prerender/prerender_helper.cc | 164 | ||||
-rw-r--r-- | chrome/renderer/prerender/prerender_helper.h | 70 |
2 files changed, 234 insertions, 0 deletions
diff --git a/chrome/renderer/prerender/prerender_helper.cc b/chrome/renderer/prerender/prerender_helper.cc new file mode 100644 index 0000000..98457bb --- /dev/null +++ b/chrome/renderer/prerender/prerender_helper.cc @@ -0,0 +1,164 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/prerender/prerender_helper.h" + +#include "base/metrics/field_trial.h" +#include "base/metrics/histogram.h" +#include "chrome/common/render_messages.h" +#include "content/renderer/navigation_state.h" +#include "content/renderer/render_view.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" + +// Helper macro for histograms. +#define RECORD_PLT(tag, perceived_page_load_time) { \ + UMA_HISTOGRAM_CUSTOM_TIMES( \ + base::FieldTrial::MakeName(std::string("Prerender.") + tag, \ + "Prefetch"), \ + perceived_page_load_time, \ + base::TimeDelta::FromMilliseconds(10), \ + base::TimeDelta::FromSeconds(60), \ + 100); \ + } + +namespace prerender { + +PrerenderHelper::PrerenderHelper(RenderView* render_view) + : RenderViewObserver(render_view), + RenderViewObserverTracker<PrerenderHelper>(render_view), + is_prerendering_(true) { +} + +PrerenderHelper::~PrerenderHelper() { +} + +// static. +bool PrerenderHelper::IsPrerendering(RenderView* render_view) { + PrerenderHelper* prerender_helper = PrerenderHelper::Get(render_view); + return (prerender_helper && prerender_helper->is_prerendering_); +} + +// static. +void PrerenderHelper::RecordHistograms( + RenderView* render_view, + const base::Time& finish_all_loads, + const base::TimeDelta& begin_to_finish_all_loads) { + static bool use_prerender_histogram = + base::FieldTrialList::Find("Prefetch") && + !base::FieldTrialList::Find("Prefetch")->group_name().empty(); + if (!use_prerender_histogram) + return; + + PrerenderHelper* prerender_helper = PrerenderHelper::Get(render_view); + + // Load time for non-prerendered pages. + if (!prerender_helper) { + RECORD_PLT("PerceivedLoadTime", begin_to_finish_all_loads); + return; + } + + if (!prerender_helper->is_prerendering_ && + !prerender_helper->HasUnrecordedData()) { + // If the RenderView has a PrerenderHelper and a histogram is being + // recorded, it should either be prerendering or have histogram data that + // has yet to be recorded. + NOTREACHED(); + delete prerender_helper; + return; + } + + // There should be a start time, since the first provisional load should have + // occured before recording any histograms. + DCHECK(!prerender_helper->prerender_start_time_.is_null()); + + // The only case where this should happen is if a page is being redirected + // prior to display. No histograms are currently recorded when the renderer + // is shutting down, so this point will never be reached in that case. + if (prerender_helper->is_prerendering_) { + DCHECK(!prerender_helper->HasUnrecordedData()); + return; + } + + // There should be a display time, since HasUnrecordedData() returned true. + DCHECK(!prerender_helper->prerender_display_time_.is_null()); + + // The RenderView still has a PrerenderHelper and is not currently being + // prerendered, so the page was prerendered and then displayed. Record + // histograms for the prerender, before deleting the PrerenderHelper. + base::Time prerender_display_time = + prerender_helper->prerender_display_time_; + base::Time prerender_start_time = prerender_helper->prerender_start_time_; + + RECORD_PLT("TimeUntilDisplayed", + prerender_display_time - prerender_start_time); + base::TimeDelta perceived_load_time = finish_all_loads - + prerender_display_time; + if (perceived_load_time < base::TimeDelta::FromSeconds(0)) { + RECORD_PLT("IdleTime", -perceived_load_time); + perceived_load_time = base::TimeDelta::FromSeconds(0); + } + RECORD_PLT("PerceivedPrerenderLoadTime", perceived_load_time); + RECORD_PLT("PerceivedLoadTime", perceived_load_time); + + // Once a prerendered page is displayed and its histograms recorded, it no + // longer needs a PrerenderHelper. + delete prerender_helper; +} + +void PrerenderHelper::WillCreateMediaPlayer( + WebKit::WebFrame* frame, + WebKit::WebMediaPlayerClient* client) { + if (is_prerendering_) { + // Cancel prerendering in the case of HTML5 media, to avoid playing sounds + // in the background. + Send(new ViewHostMsg_MaybeCancelPrerenderForHTML5Media( + render_view()->routing_id())); + } +} + +void PrerenderHelper::DidStartProvisionalLoad(WebKit::WebFrame* frame) { + // If this is the first provisional load since prerendering started, get its + // request time. + if (is_prerendering_ && prerender_start_time_.is_null()) { + WebKit::WebDataSource* data_source = frame->provisionalDataSource(); + if (!data_source) { + NOTREACHED(); + return; + } + NavigationState* navigation_state = + NavigationState::FromDataSource(data_source); + prerender_start_time_ = navigation_state->request_time(); + // The first navigation for prerendering RenderViews can only be triggered + // from PrerenderContents, so there should be a request_time. + DCHECK(!prerender_start_time_.is_null()); + } +} + +bool PrerenderHelper::OnMessageReceived( + const IPC::Message& message) { + IPC_BEGIN_MESSAGE_MAP(PrerenderHelper, message) + IPC_MESSAGE_HANDLER(ViewMsg_SetIsPrerendering, OnSetIsPrerendering) + IPC_END_MESSAGE_MAP() + // Return false on ViewMsg_SetIsPrerendering so other observers can see the + // message. + return false; +} + +void PrerenderHelper::OnSetIsPrerendering(bool is_prerendering) { + // Immediately after construction, |this| may receive the message that + // triggered its creation. If so, ignore it. + if (is_prerendering) + return; + DCHECK(!is_prerendering); + DCHECK(!HasUnrecordedData()); + + is_prerendering_ = false; + prerender_display_time_ = base::Time::Now(); +} + +bool PrerenderHelper::HasUnrecordedData() const { + return !prerender_display_time_.is_null(); +} + +} // namespace prerender diff --git a/chrome/renderer/prerender/prerender_helper.h b/chrome/renderer/prerender/prerender_helper.h new file mode 100644 index 0000000..0060287 --- /dev/null +++ b/chrome/renderer/prerender/prerender_helper.h @@ -0,0 +1,70 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PRERENDER_PRERENDER_HELPER_H_ +#define CHROME_RENDERER_PRERENDER_PRERENDER_HELPER_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "base/time.h" +#include "content/renderer/render_view_observer.h" +#include "content/renderer/render_view_observer_tracker.h" + +namespace prerender { + +// Helper class to track whether its RenderView is currently being prerendered. +// Also records prerendering-related histograms information and cancels +// prerendering when necessary, based on observed events. Created when +// prerendering starts and deleted as soon as just after the prerendering +// histograms have been recorded for a displayed prerendered page. For +// non-displayed pages, deleted on destruction of the RenderView. +class PrerenderHelper : public RenderViewObserver, + public RenderViewObserverTracker<PrerenderHelper> { + public: + explicit PrerenderHelper(RenderView* render_view); + virtual ~PrerenderHelper(); + + // Returns true if |render_view| is currently prerendering. + static bool IsPrerendering(RenderView* render_view); + + // Records prerender histograms. These are recorded even for pages that are + // not prerendered, for comparison to pages that are. + static void RecordHistograms( + RenderView* render_view, + const base::Time& finish_all_loads, + const base::TimeDelta& begin_to_finish_all_loads); + + private: + // RenderViewObserver implementation + virtual void DidStartProvisionalLoad(WebKit::WebFrame* frame) OVERRIDE; + virtual void WillCreateMediaPlayer( + WebKit::WebFrame* frame, + WebKit::WebMediaPlayerClient* client) OVERRIDE; + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + + void OnSetIsPrerendering(bool is_prerendering); + + // Returns true if the page is no longer being prerendered, but no histograms + // for the prerender have been recorded. + bool HasUnrecordedData() const; + + // Tracks whether or not observed RenderView is currently prerendering. + bool is_prerendering_; + + // Time when the prerender started. + base::Time prerender_start_time_; + // Time when the prerendered page was displayed. + base::Time prerender_display_time_; + + // Set to true when a prerendered page is displayed to prevent deletion from + // when a prerendered page is displayed until after the histograms for the + // page load have been recorded. + bool has_unrecorded_data_; + + DISALLOW_COPY_AND_ASSIGN(PrerenderHelper); +}; + +} // namespace prerender + +#endif // CHROME_RENDERER_PRERENDER_PRERENDER_HELPER_H_ |