blob: 061be81b3e65e757d430d75b23efe36d1154189c [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2022 The Chromium Authors
Max Curran6c2835ea2022-03-07 19:52:382// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Sreeja Kamishettyf66553a2022-07-14 17:41:275#ifndef CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_DOCUMENT_MANAGER_H_
6#define CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_DOCUMENT_MANAGER_H_
Max Curran6c2835ea2022-03-07 19:52:387
Max Curran646fb642022-03-16 00:44:098#include <map>
Max Curran6c2835ea2022-03-07 19:52:389
Adithya Srinivasand1c68ba2023-05-30 19:54:2510#include "base/functional/callback.h"
Max Curran18a6f2b2022-05-02 23:13:2411#include "base/memory/weak_ptr.h"
Max Curran6c2835ea2022-03-07 19:52:3812#include "content/common/content_export.h"
Max Curran6c2835ea2022-03-07 19:52:3813#include "content/public/browser/document_user_data.h"
Max Curran210cffa2022-09-06 22:24:3114#include "content/public/browser/prefetch_metrics.h"
Max Curran6c2835ea2022-03-07 19:52:3815#include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom.h"
Hiroshige Hayashizaki583b4962025-08-19 18:58:2616#include "third_party/blink/public/mojom/tokens/tokens.mojom.h"
Max Curran6c2835ea2022-03-07 19:52:3817#include "url/gurl.h"
18
19namespace content {
20
Max Curran18a6f2b2022-05-02 23:13:2421class PrefetchContainer;
Hiroshige Hayashizaki22be5e4c2025-03-07 21:39:5922class PrefetchHandle;
Max Curran18a6f2b2022-05-02 23:13:2423class PrefetchService;
Hiroshige Hayashizaki583b4962025-08-19 18:58:2624class PrefetchType;
25class PreloadPipelineInfo;
Kevin McNee7ca2e852024-04-30 02:38:3126class PreloadingPredictor;
Hiroshige Hayashizaki583b4962025-08-19 18:58:2627class SpeculationRulesTags;
28enum class PreloadingType;
Max Curran18a6f2b2022-05-02 23:13:2429
Max Curran6c2835ea2022-03-07 19:52:3830// Manages the state of and tracks metrics about prefetches for a single page
31// load.
32class CONTENT_EXPORT PrefetchDocumentManager
Kouhei Ueno136156d2024-03-12 04:26:5833 : public DocumentUserData<PrefetchDocumentManager> {
Max Curran6c2835ea2022-03-07 19:52:3834 public:
Adithya Srinivasand476f4f82023-06-20 15:55:1335 using PrefetchDestructionCallback =
36 base::RepeatingCallback<void(const GURL&)>;
Adithya Srinivasand1c68ba2023-05-30 19:54:2537
Max Curran6c2835ea2022-03-07 19:52:3838 ~PrefetchDocumentManager() override;
39
40 PrefetchDocumentManager(const PrefetchDocumentManager&) = delete;
41 const PrefetchDocumentManager operator=(const PrefetchDocumentManager&) =
42 delete;
43
Hiroshige Hayashizaki6a2bc752023-10-31 19:08:1144 // Returns the `PrefetchDocumentManager` associated with a Document if already
45 // exists, or `nullptr` otherwise.
46 static PrefetchDocumentManager* FromDocumentToken(
47 int process_id,
48 const blink::DocumentToken& document_token);
49
Max Curran646fb642022-03-16 00:44:0950 // Processes the given speculation candidates to see if they can be
51 // prefetched. Any candidates that can be prefetched are removed from
52 // |candidates|, and a prefetch for the URL of the candidate is started.
Max Curran6c2835ea2022-03-07 19:52:3853 void ProcessCandidates(
kenoss1ce36df592024-12-03 01:04:3554 std::vector<blink::mojom::SpeculationCandidatePtr>& candidates);
Max Curran6c2835ea2022-03-07 19:52:3855
Adithya Srinivasan3bdb5ce2023-06-05 13:22:1256 // Attempts to prefetch the given candidate. Returns true if a new prefetch
57 // for the candidate's URL is started.
kenoss1ce36df592024-12-03 01:04:3558 bool MaybePrefetch(blink::mojom::SpeculationCandidatePtr candidate,
59 const PreloadingPredictor& enacting_predictor);
Adithya Srinivasan3bdb5ce2023-06-05 13:22:1260
kenoss3bd73b82024-10-10 20:33:4961 void PrefetchAheadOfPrerender(
62 scoped_refptr<PreloadPipelineInfo> preload_pipeline_info,
63 blink::mojom::SpeculationCandidatePtr candidate,
64 const PreloadingPredictor& enacting_predictor);
kenoss9d57ee7b2024-06-03 01:36:4365
Max Curran646fb642022-03-16 00:44:0966 // Starts the process to prefetch |url| with the given |prefetch_type|.
Rulong Chen(陈汝龙)bf12169c2024-12-16 05:38:1667 void PrefetchUrl(const GURL& url,
68 const PrefetchType& prefetch_type,
69 const PreloadingPredictor& enacting_predictor,
Rulong Chen(陈汝龙)bf12169c2024-12-16 05:38:1670 const blink::mojom::Referrer& referrer,
Hiroki Nakagawac33034f2025-03-31 07:39:3071 std::optional<SpeculationRulesTags> speculation_rules_tags,
Rulong Chen(陈汝龙)bf12169c2024-12-16 05:38:1672 const network::mojom::NoVarySearchPtr& no_vary_search_hint,
73 scoped_refptr<PreloadPipelineInfo> preload_pipeline_info);
Max Curran6c2835ea2022-03-07 19:52:3874
Max Curran0146f852022-08-01 19:49:3375 // Checking the canary cache can be a slow and blocking operation (see
76 // crbug.com/1266018), so we only do this for the first non-decoy prefetch we
77 // make on the page.
78 bool HaveCanaryChecksStarted() const { return have_canary_checks_started_; }
79 void OnCanaryChecksStarted() { have_canary_checks_started_ = true; }
80
Max Curran210cffa2022-09-06 22:24:3181 // Returns metrics for prefetches requested by the associated page load.
82 PrefetchReferringPageMetrics& GetReferringPageMetrics() {
83 return referring_page_metrics_;
84 }
85
86 // Updates metrics when the eligibility check for a prefetch requested by this
87 // page load is completed.
88 void OnEligibilityCheckComplete(bool is_eligible);
89
90 // Updates metrics when the response for a prefetch requested by this page
91 // load is received.
Adithya Srinivasanf393dd02023-05-16 20:26:1692 void OnPrefetchSuccessful(PrefetchContainer* prefetch);
Max Curran210cffa2022-09-06 22:24:3193
Iman Sabooriab85b132022-11-15 22:17:2394 // Whether the prefetch attempt for target |url| failed or discarded
95 bool IsPrefetchAttemptFailedOrDiscarded(const GURL& url);
96
Adithya Srinivasand5e37cb2023-07-05 14:45:2397 // Returns a tuple: (can_prefetch_now, prefetch_to_evict). 'can_prefetch_now'
98 // is true if we can prefetch |next_prefetch| based on the state of the
kenoss6ccd7022025-05-20 14:24:2199 // document, and the number of existing completed prefetches. The eagerness of
100 // |next_prefetch| is taken into account when making the decision.
101 // 'prefetch_to_evict' is set to an existing prefetch if one needs to be
102 // evicted to make space for the prefetch of |next_prefetch|, or nullptr
103 // otherwise. 'prefetch_to_evict' will only be non-null if 'can_prefetch_now'
104 // is true.
Adithya Srinivasand5e37cb2023-07-05 14:45:23105 std::tuple<bool, base::WeakPtr<PrefetchContainer>> CanPrefetchNow(
106 PrefetchContainer* next_prefetch);
Adithya Srinivasanf393dd02023-05-16 20:26:16107
Adithya Srinivasand476f4f82023-06-20 15:55:13108 // See documentation for |prefetch_destruction_callback_|.
109 void SetPrefetchDestructionCallback(PrefetchDestructionCallback callback);
110
111 // Called when a PrefetchContainer started by |this| is being destroyed.
112 void PrefetchWillBeDestroyed(PrefetchContainer* prefetch);
Adithya Srinivasand1c68ba2023-05-30 19:54:25113
Max Curran5d4da4b42023-03-10 23:41:46114 base::WeakPtr<PrefetchDocumentManager> GetWeakPtr() {
115 return weak_method_factory_.GetWeakPtr();
116 }
117
Max Curran18a6f2b2022-05-02 23:13:24118 static void SetPrefetchServiceForTesting(PrefetchService* prefetch_service);
119
kenoss087ae232024-12-10 05:06:04120 void ResetPrefetchAheadOfPrerenderIfExist(const GURL& url);
121
Max Curran6c2835ea2022-03-07 19:52:38122 private:
123 explicit PrefetchDocumentManager(RenderFrameHost* rfh);
124 friend DocumentUserData;
125
Max Curranc4445fc2022-06-02 18:43:43126 // Helper function to get the |PrefetchService| associated with |this|.
127 PrefetchService* GetPrefetchService() const;
128
kenossf7d063142024-10-10 08:34:28129 bool IsPrefetchAttemptFailedOrDiscardedInternal(
130 const GURL& url,
131 PreloadingType planned_max_preloading_type);
132
Hiroshige Hayashizaki2df45292023-10-10 22:59:03133 blink::DocumentToken document_token_;
134
Max Curran646fb642022-03-16 00:44:09135 // This map holds references to all |PrefetchContainer| associated with
Hiroshige Hayashizaki7a34d0182023-11-07 20:54:34136 // |this|.
kenossf7d063142024-10-10 08:34:28137 //
138 // Keyed with `(url, planned_max_preloading_type)`.
139 // `planned_max_preloading_type == kPrerender` indicates it's ahead of
140 // prerender.
141 //
142 // We allow normal prefetch and prefetch ahead of prerender with the same key
143 // here, to handle and merge them in `PrefetchService`.
Hiroshige Hayashizaki22be5e4c2025-03-07 21:39:59144 std::map<std::pair<GURL, PreloadingType>, std::unique_ptr<PrefetchHandle>>
kenossf7d063142024-10-10 08:34:28145 all_prefetches_;
Max Curran646fb642022-03-16 00:44:09146
Max Curran0146f852022-08-01 19:49:33147 // Stores whether or not canary checks have been started for this page.
148 bool have_canary_checks_started_{false};
149
Takashi Nakayama978f0a152025-06-17 08:26:25150 // A list of immediate prefetch requests (from this page) that have completed
Adithya Srinivasan6bdb9bcbf2023-06-23 21:28:46151 // (oldest to newest).
Takashi Nakayama978f0a152025-06-17 08:26:25152 std::vector<base::WeakPtr<PrefetchContainer>> completed_immediate_prefetches_;
153 // A list of non-immediate prefetch requests (from this page) that have
154 // completed (oldest to newest).
155 std::vector<base::WeakPtr<PrefetchContainer>>
156 completed_non_immediate_prefetches_;
Adithya Srinivasanf393dd02023-05-16 20:26:16157
Max Curran210cffa2022-09-06 22:24:31158 // Metrics related to the prefetches requested by this page load.
159 PrefetchReferringPageMetrics referring_page_metrics_;
160
Adithya Srinivasand476f4f82023-06-20 15:55:13161 // Callback that is run when a prefetch started by |this| is being destroyed.
162 PrefetchDestructionCallback prefetch_destruction_callback_;
Adithya Srinivasand1c68ba2023-05-30 19:54:25163
Max Curran18a6f2b2022-05-02 23:13:24164 base::WeakPtrFactory<PrefetchDocumentManager> weak_method_factory_{this};
165
Max Curran6c2835ea2022-03-07 19:52:38166 DOCUMENT_USER_DATA_KEY_DECL();
167};
168
169} // namespace content
170
Sreeja Kamishettyf66553a2022-07-14 17:41:27171#endif // CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_DOCUMENT_MANAGER_H_