Commit 8be0266a authored by Robert Ogden's avatar Robert Ogden Committed by Commit Bot

IsolatedPrerender Starts a Spare Renderer with Experiment Param

Adds an experiment param which will start a spare renderer after all
prefetching and NSPs are complete.

Change-Id: I102031892b169e9fb2416384c4a5684ed6ac8880
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2424527
Commit-Queue: Robert Ogden <robertogden@chromium.org>
Reviewed-by: default avatarTarun Bansal <tbansal@chromium.org>
Reviewed-by: default avatarRyan Sturm <ryansturm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#813086}
parent 97c0b301
...@@ -2573,6 +2573,50 @@ IN_PROC_BROWSER_TEST_F(IsolatedPrerenderWithNSPBrowserTest, ...@@ -2573,6 +2573,50 @@ IN_PROC_BROWSER_TEST_F(IsolatedPrerenderWithNSPBrowserTest,
"IsolatedPrerender.AfterClick.Subresources.UsedCache", true, 2); "IsolatedPrerender.AfterClick.Subresources.UsedCache", true, 2);
} }
IN_PROC_BROWSER_TEST_F(IsolatedPrerenderWithNSPBrowserTest,
DISABLE_ON_WIN_MAC_CHROMEOS(StartsSpareRenderer)) {
// Enable low-end device mode to turn off automatic spare renderers. Note that
// this will also prevent NSPs from triggering, but the logic under test
// happens before that anyways.
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableLowEndDeviceMode);
base::CommandLine::ForCurrentProcess()->AppendSwitch(
"isolated-prerender-start-spare-renderer");
SetDataSaverEnabled(true);
GURL starting_page = GetOriginServerURL("/simple.html");
ui_test_utils::NavigateToURL(browser(), starting_page);
WaitForUpdatedCustomProxyConfig();
IsolatedPrerenderTabHelper* tab_helper =
IsolatedPrerenderTabHelper::FromWebContents(GetWebContents());
GURL eligible_link =
GetOriginServerURL("/prerender/isolated/prefetch_page.html");
TestTabHelperObserver tab_helper_observer(tab_helper);
tab_helper_observer.SetExpectedSuccessfulURLs({eligible_link});
base::RunLoop prefetch_run_loop;
tab_helper_observer.SetOnPrefetchSuccessfulClosure(
prefetch_run_loop.QuitClosure());
GURL doc_url("https://www.google.com/search?q=test");
MakeNavigationPrediction(doc_url, {eligible_link});
base::HistogramTester histogram_tester;
// This run loop will quit when all the prefetch responses have been
// successfully done and processed.
prefetch_run_loop.Run();
// Navigate to trigger the histogram recording.
ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
histogram_tester.ExpectUniqueSample(
"IsolatedPrerender.SpareRenderer.CountStartedOnSRP", 1, 1);
}
namespace { namespace {
std::unique_ptr<net::test_server::HttpResponse> HandleNonEligibleOrigin( std::unique_ptr<net::test_server::HttpResponse> HandleNonEligibleOrigin(
const net::test_server::HttpRequest& request) { const net::test_server::HttpRequest& request) {
......
...@@ -156,3 +156,10 @@ size_t IsolatedPrerenderMaxSubresourcesPerPrerender() { ...@@ -156,3 +156,10 @@ size_t IsolatedPrerenderMaxSubresourcesPerPrerender() {
return base::GetFieldTrialParamByFeatureAsInt( return base::GetFieldTrialParamByFeatureAsInt(
features::kIsolatePrerenders, "max_subresource_count_per_prerender", 50); features::kIsolatePrerenders, "max_subresource_count_per_prerender", 50);
} }
bool IsolatedPrerenderStartsSpareRenderer() {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
"isolated-prerender-start-spare-renderer") ||
base::GetFieldTrialParamByFeatureAsBool(features::kIsolatePrerenders,
"start_spare_renderer", false);
}
...@@ -73,4 +73,8 @@ bool IsolatedPrerenderMustHTTPProbeInsteadOfTLS(); ...@@ -73,4 +73,8 @@ bool IsolatedPrerenderMustHTTPProbeInsteadOfTLS();
// The maximum number of subresources that will be fetched per prefetched page. // The maximum number of subresources that will be fetched per prefetched page.
size_t IsolatedPrerenderMaxSubresourcesPerPrerender(); size_t IsolatedPrerenderMaxSubresourcesPerPrerender();
// Whether a spare renderer should be started after all prefetching and NSP is
// complete.
bool IsolatedPrerenderStartsSpareRenderer();
#endif // CHROME_BROWSER_PRERENDER_ISOLATED_ISOLATED_PRERENDER_PARAMS_H_ #endif // CHROME_BROWSER_PRERENDER_ISOLATED_ISOLATED_PRERENDER_PARAMS_H_
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_handle.h"
#include "content/public/browser/network_service_instance.h" #include "content/public/browser/network_service_instance.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/service_worker_context.h" #include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
...@@ -147,6 +148,23 @@ void CookieSetHelper(base::RepeatingClosure run_me, ...@@ -147,6 +148,23 @@ void CookieSetHelper(base::RepeatingClosure run_me,
run_me.Run(); run_me.Run();
} }
bool ShouldStartSpareRenderer() {
if (!IsolatedPrerenderStartsSpareRenderer()) {
return false;
}
for (content::RenderProcessHost::iterator iter(
content::RenderProcessHost::AllHostsIterator());
!iter.IsAtEnd(); iter.Advance()) {
if (iter.GetCurrentValue()->IsUnused()) {
// There is already a spare renderer.
return false;
}
}
return true;
}
} // namespace } // namespace
IsolatedPrerenderTabHelper::PrefetchMetrics::PrefetchMetrics() = default; IsolatedPrerenderTabHelper::PrefetchMetrics::PrefetchMetrics() = default;
...@@ -168,6 +186,12 @@ IsolatedPrerenderTabHelper::CurrentPageLoad::CurrentPageLoad( ...@@ -168,6 +186,12 @@ IsolatedPrerenderTabHelper::CurrentPageLoad::CurrentPageLoad(
} }
IsolatedPrerenderTabHelper::CurrentPageLoad::~CurrentPageLoad() { IsolatedPrerenderTabHelper::CurrentPageLoad::~CurrentPageLoad() {
if (IsolatedPrerenderStartsSpareRenderer()) {
UMA_HISTOGRAM_COUNTS_100(
"IsolatedPrerender.SpareRenderer.CountStartedOnSRP",
number_of_spare_renderers_started_);
}
if (!profile_) if (!profile_)
return; return;
...@@ -680,6 +704,12 @@ void IsolatedPrerenderTabHelper::StartSinglePrefetch() { ...@@ -680,6 +704,12 @@ void IsolatedPrerenderTabHelper::StartSinglePrefetch() {
IsolatedPrerenderMainframeBodyLengthLimit()); IsolatedPrerenderMainframeBodyLengthLimit());
page_->url_loaders_.emplace(std::move(loader)); page_->url_loaders_.emplace(std::move(loader));
// Start a spare renderer now so that it will be ready by the time it is
// useful to have.
if (ShouldStartSpareRenderer()) {
StartSpareRenderer();
}
} }
void IsolatedPrerenderTabHelper::OnPrefetchRedirect( void IsolatedPrerenderTabHelper::OnPrefetchRedirect(
...@@ -922,6 +952,12 @@ void IsolatedPrerenderTabHelper::DoNoStatePrefetch() { ...@@ -922,6 +952,12 @@ void IsolatedPrerenderTabHelper::DoNoStatePrefetch() {
void IsolatedPrerenderTabHelper::OnPrerenderDone(const GURL& url) { void IsolatedPrerenderTabHelper::OnPrerenderDone(const GURL& url) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// The completed NSP probably consumed a previously started spare renderer, so
// kick off another one if needed.
if (ShouldStartSpareRenderer()) {
StartSpareRenderer();
}
// It is possible that this is run as a callback after a navigation has // It is possible that this is run as a callback after a navigation has
// already happened and |page_| is now a different instance than when the // already happened and |page_| is now a different instance than when the
// prerender was started. In this case, just return. // prerender was started. In this case, just return.
...@@ -943,6 +979,11 @@ void IsolatedPrerenderTabHelper::OnPrerenderDone(const GURL& url) { ...@@ -943,6 +979,11 @@ void IsolatedPrerenderTabHelper::OnPrerenderDone(const GURL& url) {
DoNoStatePrefetch(); DoNoStatePrefetch();
} }
void IsolatedPrerenderTabHelper::StartSpareRenderer() {
page_->number_of_spare_renderers_started_++;
content::RenderProcessHost::WarmupSpareRenderProcessHost(profile_);
}
void IsolatedPrerenderTabHelper::OnPredictionUpdated( void IsolatedPrerenderTabHelper::OnPredictionUpdated(
const base::Optional<NavigationPredictorKeyedService::Prediction> const base::Optional<NavigationPredictorKeyedService::Prediction>
prediction) { prediction) {
......
...@@ -362,6 +362,9 @@ class IsolatedPrerenderTabHelper ...@@ -362,6 +362,9 @@ class IsolatedPrerenderTabHelper
// The number of no state prefetch requests that have been made. // The number of no state prefetch requests that have been made.
size_t number_of_no_state_prefetch_attempts_ = 0; size_t number_of_no_state_prefetch_attempts_ = 0;
// The number of spare renderers that were started during this page load.
size_t number_of_spare_renderers_started_ = 0;
// All urls that are eligible to be no state prefetched. Once a no state // All urls that are eligible to be no state prefetched. Once a no state
// prefetch finishes, in success or in error, it is removed from this list. // prefetch finishes, in success or in error, it is removed from this list.
// If there is an active no state prefetch, its url will always be the first // If there is an active no state prefetch, its url will always be the first
...@@ -445,6 +448,10 @@ class IsolatedPrerenderTabHelper ...@@ -445,6 +448,10 @@ class IsolatedPrerenderTabHelper
// Starts a new no state prefetch for the next eligible url. // Starts a new no state prefetch for the next eligible url.
void DoNoStatePrefetch(); void DoNoStatePrefetch();
// Starts a spare renderer. Should only be called when all NSPs and
// prefetching is complete.
void StartSpareRenderer();
// Makes a clone of |this|'s prefetch response so that it can be used for // Makes a clone of |this|'s prefetch response so that it can be used for
// NoStatePrefetch now and later reused if the user navigates to that page. // NoStatePrefetch now and later reused if the user navigates to that page.
std::unique_ptr<PrefetchedMainframeResponseContainer> std::unique_ptr<PrefetchedMainframeResponseContainer>
......
...@@ -6862,6 +6862,17 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. ...@@ -6862,6 +6862,17 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
</summary> </summary>
</histogram> </histogram>
<histogram name="IsolatedPrerender.SpareRenderer.CountStartedOnSRP"
units="count" expires_after="M90">
<owner>robertogden@chromium.org</owner>
<owner>ryansturm@chromium.org</owner>
<owner>tbansal@chromium.org</owner>
<summary>
Records the number of spare renderers that were attempted to be started on
the SRP, when the feature param is enabled.
</summary>
</histogram>
<histogram name="JSDialogs.OnBeforeUnloadStayVsLeave" enum="StayVsLeave" <histogram name="JSDialogs.OnBeforeUnloadStayVsLeave" enum="StayVsLeave"
expires_after="M77"> expires_after="M77">
<owner>avi@chromium.org</owner> <owner>avi@chromium.org</owner>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment