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

Side by Side Diff: chrome/browser/page_load_metrics/metrics_web_contents_observer.cc

Issue 2624283004: Associate a main resource request with its PageLoadTracker. (Closed)
Patch Set: comment cleanup Created 3 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" 5 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <ostream> 8 #include <ostream>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/metrics/user_metrics.h" 15 #include "base/metrics/user_metrics.h"
16 #include "chrome/browser/page_load_metrics/browser_page_track_decider.h" 16 #include "chrome/browser/page_load_metrics/browser_page_track_decider.h"
17 #include "chrome/browser/page_load_metrics/page_load_metrics_embedder_interface. h" 17 #include "chrome/browser/page_load_metrics/page_load_metrics_embedder_interface. h"
18 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" 18 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h"
19 #include "chrome/browser/page_load_metrics/page_load_tracker.h" 19 #include "chrome/browser/page_load_metrics/page_load_tracker.h"
20 #include "chrome/common/page_load_metrics/page_load_metrics_messages.h" 20 #include "chrome/common/page_load_metrics/page_load_metrics_messages.h"
21 #include "chrome/common/page_load_metrics/page_load_timing.h" 21 #include "chrome/common/page_load_metrics/page_load_timing.h"
22 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/global_request_id.h"
23 #include "content/public/browser/navigation_details.h" 24 #include "content/public/browser/navigation_details.h"
24 #include "content/public/browser/navigation_handle.h" 25 #include "content/public/browser/navigation_handle.h"
25 #include "content/public/browser/render_frame_host.h" 26 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/render_view_host.h" 27 #include "content/public/browser/render_view_host.h"
27 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
28 #include "content/public/browser/web_contents_observer.h" 29 #include "content/public/browser/web_contents_observer.h"
29 #include "content/public/browser/web_contents_user_data.h" 30 #include "content/public/browser/web_contents_user_data.h"
30 #include "ipc/ipc_message.h" 31 #include "ipc/ipc_message.h"
31 #include "ipc/ipc_message_macros.h" 32 #include "ipc/ipc_message_macros.h"
32 #include "net/base/net_errors.h" 33 #include "net/base/net_errors.h"
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 // after the PageLoadTracker. The PageLoadTracker does not hold on to 169 // after the PageLoadTracker. The PageLoadTracker does not hold on to
169 // committed_load_ or navigation_handle beyond the scope of the constructor. 170 // committed_load_ or navigation_handle beyond the scope of the constructor.
170 provisional_loads_.insert(std::make_pair( 171 provisional_loads_.insert(std::make_pair(
171 navigation_handle, 172 navigation_handle,
172 base::MakeUnique<PageLoadTracker>( 173 base::MakeUnique<PageLoadTracker>(
173 in_foreground_, embedder_interface_.get(), currently_committed_url, 174 in_foreground_, embedder_interface_.get(), currently_committed_url,
174 navigation_handle, user_initiated_info, chain_size, 175 navigation_handle, user_initiated_info, chain_size,
175 chain_size_same_url))); 176 chain_size_same_url)));
176 } 177 }
177 178
179 PageLoadTracker* MetricsWebContentsObserver::GetTrackerOrNullForRequest(
180 const content::GlobalRequestID& request_id,
181 content::ResourceType resource_type,
182 base::TimeTicks creation_time) {
183 if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME) {
184 // The main frame request can complete either before or after commit, so we
185 // look at both provisional loads and the committed load to find a
186 // PageLoadTracker with a matching request id. See
187 // https://docs.google.com/document/d/1dZP0si0IKEMeVKGsohJ3fFWiKqh3nZBtuTFVk APSXYM/edit
Charlie Harrison 2017/01/13 15:56:23 optional: Can you shorten this with a https://goo.
Bryan McQuade 2017/01/17 15:06:26 done
188 // for more details.
189 for (const auto& kv : provisional_loads_) {
RyanSturm 2017/01/13 15:39:50 I'd actually suggest going a step further for the
Bryan McQuade 2017/01/13 15:47:14 Ah, interesting, what problem would we solve by st
Bryan McQuade 2017/01/13 15:53:17 Ah, maybe you are concerned that we won't have the
RyanSturm 2017/01/13 16:15:46 Like you said, clamy@ is the expert here, but I be
190 PageLoadTracker* candidate = kv.second.get();
191 if (candidate->HasMatchingNavigationRequestID(request_id)) {
192 return candidate;
193 }
194 }
195 if (committed_load_ &&
196 committed_load_->HasMatchingNavigationRequestID(request_id)) {
197 return committed_load_.get();
198 }
199 } else {
200 // Non main frame resources are always associated with the currently
201 // committed load. If the resource request was started before this
202 // navigation then it should be ignored.
203
204 // TODO(jkarlin): There is a race here. Consider the following sequence:
205 // 1. renderer has a committed page A
206 // 2. navigation is initiated to page B
207 // 3. page A initiates URLRequests (e.g. in the unload handler)
208 // 4. page B commits
209 // 5. the URLRequests initiated by A complete
Charlie Harrison 2017/01/13 15:56:23 Shouldn't the request be cancelled? I guess it cou
Bryan McQuade 2017/01/17 15:06:26 Unfortunately that doesn't seem to be the case. I
210 // In the above example, the URLRequests initiated by A will be attributed
211 // to page load B. This should be relatively rare but we may want to fix
212 // this at some point. We could fix this by comparing the URLRequest
213 // creation time against the committed load's commit time, however more
214 // investigation is needed to confirm that all cases would be handled
215 // correctly (for example Link: preloads).
216 if (committed_load_ &&
217 creation_time >= committed_load_->navigation_start()) {
218 return committed_load_.get();
219 }
220 }
221 return nullptr;
222 }
223
178 void MetricsWebContentsObserver::OnRequestComplete( 224 void MetricsWebContentsObserver::OnRequestComplete(
225 const content::GlobalRequestID& request_id,
179 content::ResourceType resource_type, 226 content::ResourceType resource_type,
180 bool was_cached, 227 bool was_cached,
181 bool used_data_reduction_proxy, 228 bool used_data_reduction_proxy,
182 int64_t raw_body_bytes, 229 int64_t raw_body_bytes,
183 int64_t original_content_length, 230 int64_t original_content_length,
184 base::TimeTicks creation_time) { 231 base::TimeTicks creation_time) {
185 // If the navigation hasn't committed yet then we'll miss the resource (this 232 PageLoadTracker* tracker =
186 // happens on the new tab page). Also, if the resource request was started 233 GetTrackerOrNullForRequest(request_id, resource_type, creation_time);
187 // before this navigation then it should be ignored. 234 if (tracker) {
188 // TODO(jkarlin): There is a race here. If a renderer starts URLRequests for 235 ExtraRequestInfo extra_request_info(
189 // page A after navigating (but before comitting) to page B, then page A's 236 was_cached, raw_body_bytes, used_data_reduction_proxy,
190 // requests might wind up counting toward page B's size. This should be 237 was_cached ? 0 : original_content_length);
191 // relatively rare but we may want to fix this at some point. 238 tracker->OnLoadedResource(extra_request_info);
192 if (!committed_load_ || creation_time < committed_load_->navigation_start()) {
193 return;
194 } 239 }
195
196 ExtraRequestInfo extra_request_info(was_cached, raw_body_bytes,
197 used_data_reduction_proxy,
198 was_cached ? 0 : original_content_length);
199
200 committed_load_->OnLoadedResource(extra_request_info);
201 } 240 }
202 241
203 const PageLoadExtraInfo 242 const PageLoadExtraInfo
204 MetricsWebContentsObserver::GetPageLoadExtraInfoForCommittedLoad() { 243 MetricsWebContentsObserver::GetPageLoadExtraInfoForCommittedLoad() {
205 DCHECK(committed_load_); 244 DCHECK(committed_load_);
206 return committed_load_->ComputePageLoadExtraInfo(); 245 return committed_load_->ComputePageLoadExtraInfo();
207 } 246 }
208 247
248 void MetricsWebContentsObserver::ReadyToCommitNavigation(
249 content::NavigationHandle* navigation_handle) {
250 auto it = provisional_loads_.find(navigation_handle);
251 if (it == provisional_loads_.end())
252 return;
253 it->second->ReadyToCommit(navigation_handle);
254 }
255
209 void MetricsWebContentsObserver::DidFinishNavigation( 256 void MetricsWebContentsObserver::DidFinishNavigation(
210 content::NavigationHandle* navigation_handle) { 257 content::NavigationHandle* navigation_handle) {
211 if (!navigation_handle->IsInMainFrame()) 258 if (!navigation_handle->IsInMainFrame())
212 return; 259 return;
213 260
214 std::unique_ptr<PageLoadTracker> finished_nav( 261 std::unique_ptr<PageLoadTracker> finished_nav(
215 std::move(provisional_loads_[navigation_handle])); 262 std::move(provisional_loads_[navigation_handle]));
216 provisional_loads_.erase(navigation_handle); 263 provisional_loads_.erase(navigation_handle);
217 264
218 // Ignore same-page navigations. 265 // Ignore same-page navigations.
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 content::NavigationHandle* navigation_handle) const { 530 content::NavigationHandle* navigation_handle) const {
484 DCHECK(navigation_handle->IsInMainFrame()); 531 DCHECK(navigation_handle->IsInMainFrame());
485 DCHECK(!navigation_handle->HasCommitted() || 532 DCHECK(!navigation_handle->HasCommitted() ||
486 !navigation_handle->IsSamePage()); 533 !navigation_handle->IsSamePage());
487 534
488 return BrowserPageTrackDecider(embedder_interface_.get(), web_contents(), 535 return BrowserPageTrackDecider(embedder_interface_.get(), web_contents(),
489 navigation_handle).ShouldTrack(); 536 navigation_handle).ShouldTrack();
490 } 537 }
491 538
492 } // namespace page_load_metrics 539 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698