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

Unified Diff: chrome/browser/page_load_metrics/page_load_tracker.cc

Issue 2885053002: Buffer timing callbacks until timing state converges. (Closed)
Patch Set: address comments Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/page_load_metrics/page_load_tracker.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/page_load_metrics/page_load_tracker.cc
diff --git a/chrome/browser/page_load_metrics/page_load_tracker.cc b/chrome/browser/page_load_metrics/page_load_tracker.cc
index 77d31f62cb34f6d1d91ea4d8c66f759988976674..fbad01c9140dc1c3af69ab4836c1ac571d5dae3e 100644
--- a/chrome/browser/page_load_metrics/page_load_tracker.cc
+++ b/chrome/browser/page_load_metrics/page_load_tracker.cc
@@ -63,6 +63,8 @@ const char kPageLoadStartedInForeground[] =
"PageLoad.Internal.NavigationStartedInForeground";
const char kPageLoadPrerender[] = "PageLoad.Internal.Prerender";
const char kPageLoadTimingStatus[] = "PageLoad.Internal.PageLoadTimingStatus";
+const char kPageLoadTimingDispatchStatus[] =
+ "PageLoad.Internal.PageLoadTimingStatus.AtTimingCallbackDispatch";
} // namespace internal
@@ -642,19 +644,10 @@ void PageLoadTracker::UpdateSubFrameTiming(
}
base::TimeDelta navigation_start_offset = it->second;
- const PageLoadTiming last_timing = merged_page_timing_;
MergePaintTiming(navigation_start_offset, new_timing.paint_timing,
false /* is_main_frame */);
- if (last_timing == merged_page_timing_)
- return;
-
- const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
- for (const auto& observer : observers_) {
- DispatchObserverTimingCallbacks(observer.get(), last_timing,
- merged_page_timing_, main_frame_metadata_,
- info);
- }
+ DispatchTimingUpdates();
}
void PageLoadTracker::MergePaintTiming(
@@ -733,22 +726,56 @@ void PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing,
// Thus, we make a copy of timing here, update timing_ and
// main_frame_metadata_, and then proceed to dispatch the observer timing
// callbacks.
- const PageLoadTiming last_timing = merged_page_timing_;
+ const PaintTiming last_paint_timing = merged_page_timing_.paint_timing;
// Update the merged_page_timing_, making sure to merge the previously
// observed |paint_timing|, which is tracked across all frames in the page.
merged_page_timing_ = new_timing;
- merged_page_timing_.paint_timing = last_timing.paint_timing;
+ merged_page_timing_.paint_timing = last_paint_timing;
MergePaintTiming(base::TimeDelta(), new_timing.paint_timing,
true /* is_main_frame */);
- const PageLoadMetadata last_metadata = main_frame_metadata_;
main_frame_metadata_ = new_metadata;
+
+ DispatchTimingUpdates();
+}
+
+void PageLoadTracker::DispatchTimingUpdates() {
+ if (last_dispatched_merged_page_timing_ == merged_page_timing_ &&
+ last_dispatched_main_frame_metadata_ == main_frame_metadata_) {
+ return;
+ }
+
+ if (merged_page_timing_.paint_timing.first_paint) {
+ if (!merged_page_timing_.parse_timing.parse_start ||
+ !merged_page_timing_.document_timing.first_layout) {
+ // When merging paint events across frames, we can sometimes encounter
+ // cases where we've received a first paint event for a child frame before
+ // receiving required earlier events in the main frame, due to buffering
+ // in the render process which results in out of order delivery. For
+ // example, we may receive a notification for a first paint in a child
+ // frame before we've received a notification for parse start or first
+ // layout in the main frame. In these cases, we delay sending timing
+ // updates until we've received all expected events (e.g. wait to receive
+ // a parse or layout event before dispatching a paint event), so observers
+ // can make assumptions about ordering of these events in their callbacks.
+ return;
+ }
+ }
+
+ internal::PageLoadTimingStatus status =
+ IsValidPageLoadTiming(merged_page_timing_);
+ UMA_HISTOGRAM_ENUMERATION(internal::kPageLoadTimingDispatchStatus, status,
+ internal::LAST_PAGE_LOAD_TIMING_STATUS);
+
const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
for (const auto& observer : observers_) {
- DispatchObserverTimingCallbacks(observer.get(), last_timing,
- merged_page_timing_, last_metadata, info);
+ DispatchObserverTimingCallbacks(
+ observer.get(), last_dispatched_merged_page_timing_,
+ merged_page_timing_, last_dispatched_main_frame_metadata_, info);
}
+ last_dispatched_merged_page_timing_ = merged_page_timing_;
+ last_dispatched_main_frame_metadata_ = main_frame_metadata_;
}
void PageLoadTracker::OnStartedResource(
« no previous file with comments | « chrome/browser/page_load_metrics/page_load_tracker.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698