From 25376e183109746ae6ba2fd34359de0a7ae9fc22 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Wed, 31 May 2023 02:30:58 +0000 Subject: [PATCH] [M115] preload: Integrate preconnect with bookmark triggers This CL integrate preconnect with bookmark trigger. (cherry picked from commit 2bb9561185604c6b4fff1c66d50eb0c659701857) Bug: 1422819, 1448795 Change-Id: Iacb7f8e637c0ab130671c38fd3d95ad4b36036dc Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4531590 Reviewed-by: Sreeja Kamishetty Commit-Queue: Huanpo Lin Reviewed-by: Scott Violet Reviewed-by: Takashi Toyoshima Cr-Original-Commit-Position: refs/heads/main@{#1149027} Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4569830 Cr-Commit-Position: refs/branch-heads/5790@{#164} Cr-Branched-From: 1d71a337b1f6e707a13ae074dca1e2c34905eb9f-refs/heads/main@{#1148114} --- .../browser/predictors/loading_predictor.cc | 36 ++++++++++++++ chrome/browser/predictors/loading_predictor.h | 8 ++++ .../predictors/loading_predictor_config.h | 3 ++ .../ui/views/bookmarks/bookmark_bar_view.cc | 48 +++++++++++++++++-- .../bookmark_bar_view_browsertest.cc | 3 +- 5 files changed, 92 insertions(+), 6 deletions(-) diff --git a/chrome/browser/predictors/loading_predictor.cc b/chrome/browser/predictors/loading_predictor.cc index 9c74c8e969663..debff8acb6f05 100644 --- a/chrome/browser/predictors/loading_predictor.cc +++ b/chrome/browser/predictors/loading_predictor.cc @@ -121,6 +121,12 @@ bool LoadingPredictor::PrepareForPageLoad( return true; } + if (origin == HintOrigin::BOOKMARK_BAR) { + // Bookmark hints are lightweight and need a special treatment. + HandleBookmarkBarHint(url, preconnectable); + return true; + } + PreconnectPrediction prediction; bool has_local_preconnect_prediction = false; if (features::ShouldUseLocalPredictions()) { @@ -342,6 +348,36 @@ void LoadingPredictor::HandleOmniboxHint(const GURL& url, bool preconnectable) { } } +void LoadingPredictor::HandleBookmarkBarHint(const GURL& url, + bool preconnectable) { + if (!url.is_valid() || !url.has_host() || !IsPreconnectAllowed(profile_)) { + return; + } + + url::Origin origin = url::Origin::Create(url); + bool is_new_origin = origin != last_bookmark_bar_origin_; + last_bookmark_bar_origin_ = origin; + net::SchemefulSite site = net::SchemefulSite(origin); + auto network_anonymization_key = + net::NetworkAnonymizationKey::CreateSameSite(site); + base::TimeTicks now = base::TimeTicks::Now(); + if (preconnectable && url.SchemeIs("https")) { + if (is_new_origin || now - last_bookmark_bar_preconnect_time_ >= + kMinDelayBetweenPreconnectRequests) { + last_bookmark_bar_preconnect_time_ = now; + preconnect_manager()->StartPreconnectUrl(url, true, + network_anonymization_key); + } + return; + } + + if (is_new_origin || now - last_bookmark_bar_preresolve_time_ >= + kMinDelayBetweenPreresolveRequests) { + last_bookmark_bar_preresolve_time_ = now; + preconnect_manager()->StartPreresolveHost(url, network_anonymization_key); + } +} + void LoadingPredictor::PreconnectInitiated(const GURL& url, const GURL& preconnect_url) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); diff --git a/chrome/browser/predictors/loading_predictor.h b/chrome/browser/predictors/loading_predictor.h index 218b805187aff..945d7425bb8a8 100644 --- a/chrome/browser/predictors/loading_predictor.h +++ b/chrome/browser/predictors/loading_predictor.h @@ -151,6 +151,10 @@ class LoadingPredictor : public KeyedService, // indicates if preconnect is possible. void HandleOmniboxHint(const GURL& url, bool preconnectable); + // May start a preconnect or a preresolve for |url|. |preconnectable| + // indicates if preconnect is possible. + void HandleBookmarkBarHint(const GURL& url, bool preconnectable); + // For testing. void set_mock_resource_prefetch_predictor( std::unique_ptr predictor) { @@ -186,6 +190,10 @@ class LoadingPredictor : public KeyedService, base::TimeTicks last_omnibox_preconnect_time_; base::TimeTicks last_omnibox_preresolve_time_; + url::Origin last_bookmark_bar_origin_; + base::TimeTicks last_bookmark_bar_preconnect_time_; + base::TimeTicks last_bookmark_bar_preresolve_time_; + friend class LoadingPredictorTest; friend class LoadingPredictorPreconnectTest; friend class LoadingPredictorTabHelperTest; diff --git a/chrome/browser/predictors/loading_predictor_config.h b/chrome/browser/predictors/loading_predictor_config.h index e2b0e8e62aac1..b13d9831abf1c 100644 --- a/chrome/browser/predictors/loading_predictor_config.h +++ b/chrome/browser/predictors/loading_predictor_config.h @@ -50,6 +50,9 @@ enum class HintOrigin { // Triggered by optimization guide. OPTIMIZATION_GUIDE, + + // Triggered by bookmark bar. + BOOKMARK_BAR, }; // Gets the string that can be used to record histograms for the hint origin. diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index ae89a6c8b4d49..6b2af6271eba3 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc @@ -38,6 +38,9 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/defaults.h" #include "chrome/browser/favicon/favicon_utils.h" +#include "chrome/browser/predictors/loading_predictor.h" +#include "chrome/browser/predictors/loading_predictor_config.h" +#include "chrome/browser/predictors/loading_predictor_factory.h" #include "chrome/browser/preloading/chrome_preloading.h" #include "chrome/browser/preloading/prerender/prerender_manager.h" #include "chrome/browser/profiles/profile.h" @@ -195,7 +198,10 @@ enum class PrerenderPredictionResult { }; // These are used as control the behavior of kBookmarkTriggerForPrerender2. -const base::FeatureParam kPrerenderStartDelayOnMouseHoverByMiliSeconds{ +const base::FeatureParam kPreconnectStartDelayOnMouseHoverByMiliseconds{ + &features::kBookmarkTriggerForPrerender2, + "preconnect_start_delay_on_mouse_hover_ms", 100}; +const base::FeatureParam kPrerenderStartDelayOnMouseHoverByMiliseconds{ &features::kBookmarkTriggerForPrerender2, "prerender_start_delay_on_mouse_hover_ms", 300}; const base::FeatureParam kPrerenderBookmarkBarOnMousePressedTrigger{ @@ -380,10 +386,9 @@ class BookmarkButton : public BookmarkButtonBase { preloading_timer_.Start( FROM_HERE, base::Milliseconds( - kPrerenderStartDelayOnMouseHoverByMiliSeconds.Get()), - base::BindRepeating( - &BookmarkButton::StartPrerendering, base::Unretained(this), - chrome_preloading_predictor::kMouseHoverOnBookmarkBar, *url_)); + kPreconnectStartDelayOnMouseHoverByMiliseconds.Get()), + base::BindRepeating(&BookmarkButton::StartPreconnecting, + base::Unretained(this), *url_)); } } @@ -439,6 +444,39 @@ class BookmarkButton : public BookmarkButtonBase { } private: + void StartPreconnecting(GURL url) { + CHECK( + base::FeatureList::IsEnabled(features::kBookmarkTriggerForPrerender2)); + if (prerender_handle_) { + return; + } + + // Directly start prerendering to avoid timer overhead. + if (kPrerenderStartDelayOnMouseHoverByMiliseconds.Get() - + kPreconnectStartDelayOnMouseHoverByMiliseconds.Get() <= + 0) { + StartPrerendering(chrome_preloading_predictor::kMouseHoverOnBookmarkBar, + url); + } else { + auto* loading_predictor = + predictors::LoadingPredictorFactory::GetForProfile( + browser_->profile()); + if (loading_predictor) { + loading_predictor->PrepareForPageLoad( + url, predictors::HintOrigin::BOOKMARK_BAR, true); + } + + preloading_timer_.Start( + FROM_HERE, + base::Milliseconds( + kPrerenderStartDelayOnMouseHoverByMiliseconds.Get() - + kPreconnectStartDelayOnMouseHoverByMiliseconds.Get()), + base::BindRepeating( + &BookmarkButton::StartPrerendering, base::Unretained(this), + chrome_preloading_predictor::kMouseHoverOnBookmarkBar, url)); + } + } + void StartPrerendering(content::PreloadingPredictor predictor, GURL url) { // TODO(https://crbug.com/1422819): Prerender only for https scheme, and add // an enum metric to report the protocol scheme. diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_browsertest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_browsertest.cc index 58c6a2a523bbc..34caa0c8264ef 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_browsertest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_browsertest.cc @@ -492,7 +492,8 @@ class PrerenderBookmarkBarOnHoverNavigationTest scoped_feature_list_.InitWithFeaturesAndParameters( { {features::kBookmarkTriggerForPrerender2, - {{"prerender_start_delay_on_mouse_hover_ms", "0"}, + {{"preconnect_start_delay_on_mouse_hover_ms", "0"}, + {"prerender_start_delay_on_mouse_hover_ms", "0"}, {"prerender_bookmarkbar_on_mouse_pressed_trigger", "false"}, {"prerender_bookmarkbar_on_mouse_hover_trigger", "true"}}}, },