Commit ef514667 authored by Liquan(Max) Gu's avatar Liquan(Max) Gu Committed by Commit Bot

[FCP++] Allow time==0 to be propagated to UKM/UMA

Currently, LargestImagePaint, LargestTextPaint with time==0 are treated as
null and are not propagated to UMA/UKM. As we are changing to use time==0 &&
size>0 to represent that the largest content is still loading, we should
allow time==0 to be propagated to UMA/UKM.

Bug: 949974
Change-Id: I55c6d148d4a91b366fbf519a551a15f197d47b79
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1606800
Commit-Queue: Liquan (Max) Gu <maxlg@chromium.org>
Reviewed-by: default avatarBryan McQuade <bmcquade@chromium.org>
Cr-Commit-Position: refs/heads/master@{#663180}
parent 23b32261
...@@ -820,7 +820,7 @@ void CorePageLoadMetricsObserver::RecordTimingHistograms( ...@@ -820,7 +820,7 @@ void CorePageLoadMetricsObserver::RecordTimingHistograms(
largest_content_type); largest_content_type);
} }
const page_load_metrics::TimingInfo& paint = const page_load_metrics::ContentfulPaintTimingInfo& paint =
largest_contentful_paint_handler_.MergeMainFrameAndSubframes(); largest_contentful_paint_handler_.MergeMainFrameAndSubframes();
if (!paint.IsEmpty() && if (!paint.IsEmpty() &&
WasStartedInForegroundOptionalEventInForeground(paint.Time(), info)) { WasStartedInForegroundOptionalEventInForeground(paint.Time(), info)) {
......
...@@ -16,8 +16,9 @@ static bool g_disable_subframe_navigation_start_offset = false; ...@@ -16,8 +16,9 @@ static bool g_disable_subframe_navigation_start_offset = false;
namespace { namespace {
const TimingInfo& MergeTimingsBySizeAndTime(const TimingInfo& timing1, const ContentfulPaintTimingInfo& MergeTimingsBySizeAndTime(
const TimingInfo& timing2) { const ContentfulPaintTimingInfo& timing1,
const ContentfulPaintTimingInfo& timing2) {
// When both are empty, just return either. // When both are empty, just return either.
if (timing1.IsEmpty() && timing2.IsEmpty()) if (timing1.IsEmpty() && timing2.IsEmpty())
return timing1; return timing1;
...@@ -39,19 +40,19 @@ const TimingInfo& MergeTimingsBySizeAndTime(const TimingInfo& timing1, ...@@ -39,19 +40,19 @@ const TimingInfo& MergeTimingsBySizeAndTime(const TimingInfo& timing1,
} }
void MergeForSubframesWithAdjustedTime( void MergeForSubframesWithAdjustedTime(
TimingInfo* inout_timing, ContentfulPaintTimingInfo* inout_timing,
const base::Optional<base::TimeDelta>& candidate_new_time, const base::Optional<base::TimeDelta>& candidate_new_time,
const uint64_t& candidate_new_size) { const uint64_t& candidate_new_size) {
DCHECK(inout_timing); DCHECK(inout_timing);
const TimingInfo new_candidate(candidate_new_time, candidate_new_size, const ContentfulPaintTimingInfo new_candidate(
inout_timing->Type()); candidate_new_time, candidate_new_size, inout_timing->Type());
const TimingInfo& merged_candidate = const ContentfulPaintTimingInfo& merged_candidate =
MergeTimingsBySizeAndTime(new_candidate, *inout_timing); MergeTimingsBySizeAndTime(new_candidate, *inout_timing);
inout_timing->Reset(merged_candidate.Time(), merged_candidate.Size()); inout_timing->Reset(merged_candidate.Time(), merged_candidate.Size());
} }
void MergeForSubframes( void MergeForSubframes(
TimingInfo* inout_timing, ContentfulPaintTimingInfo* inout_timing,
const base::Optional<base::TimeDelta>& candidate_new_time, const base::Optional<base::TimeDelta>& candidate_new_time,
const uint64_t& candidate_new_size, const uint64_t& candidate_new_size,
base::TimeDelta navigation_start_offset) { base::TimeDelta navigation_start_offset) {
...@@ -68,18 +69,20 @@ bool IsSubframe(content::RenderFrameHost* subframe_rfh) { ...@@ -68,18 +69,20 @@ bool IsSubframe(content::RenderFrameHost* subframe_rfh) {
} // namespace } // namespace
TimingInfo::TimingInfo(PageLoadMetricsObserver::LargestContentType type) ContentfulPaintTimingInfo::ContentfulPaintTimingInfo(
PageLoadMetricsObserver::LargestContentType type)
: time_(base::Optional<base::TimeDelta>()), size_(0), type_(type) {} : time_(base::Optional<base::TimeDelta>()), size_(0), type_(type) {}
TimingInfo::TimingInfo( ContentfulPaintTimingInfo::ContentfulPaintTimingInfo(
const base::Optional<base::TimeDelta>& time, const base::Optional<base::TimeDelta>& time,
const uint64_t& size, const uint64_t& size,
const page_load_metrics::PageLoadMetricsObserver::LargestContentType type) const page_load_metrics::PageLoadMetricsObserver::LargestContentType type)
: time_(time), size_(size), type_(type) {} : time_(time), size_(size), type_(type) {}
TimingInfo::TimingInfo(const TimingInfo& other) = default; ContentfulPaintTimingInfo::ContentfulPaintTimingInfo(
const ContentfulPaintTimingInfo& other) = default;
std::unique_ptr<base::trace_event::TracedValue> TimingInfo::DataAsTraceValue() std::unique_ptr<base::trace_event::TracedValue>
const { ContentfulPaintTimingInfo::DataAsTraceValue() const {
std::unique_ptr<base::trace_event::TracedValue> data = std::unique_ptr<base::trace_event::TracedValue> data =
std::make_unique<base::trace_event::TracedValue>(); std::make_unique<base::trace_event::TracedValue>();
data->SetInteger("durationInMilliseconds", time_.value().InMilliseconds()); data->SetInteger("durationInMilliseconds", time_.value().InMilliseconds());
...@@ -88,7 +91,7 @@ std::unique_ptr<base::trace_event::TracedValue> TimingInfo::DataAsTraceValue() ...@@ -88,7 +91,7 @@ std::unique_ptr<base::trace_event::TracedValue> TimingInfo::DataAsTraceValue()
return data; return data;
} }
std::string TimingInfo::TypeInString() const { std::string ContentfulPaintTimingInfo::TypeInString() const {
switch (Type()) { switch (Type()) {
case page_load_metrics::PageLoadMetricsObserver::LargestContentType::kText: case page_load_metrics::PageLoadMetricsObserver::LargestContentType::kText:
return "text"; return "text";
...@@ -105,18 +108,18 @@ void LargestContentfulPaintHandler::SetTestMode(bool enabled) { ...@@ -105,18 +108,18 @@ void LargestContentfulPaintHandler::SetTestMode(bool enabled) {
g_disable_subframe_navigation_start_offset = enabled; g_disable_subframe_navigation_start_offset = enabled;
} }
void TimingInfo::Reset(const base::Optional<base::TimeDelta>& time, void ContentfulPaintTimingInfo::Reset(
const base::Optional<base::TimeDelta>& time,
const uint64_t& size) { const uint64_t& size) {
size_ = size; size_ = size;
time_ = time; time_ = time;
DCHECK(HasConsistentTimeAndSize());
} }
ContentfulPaint::ContentfulPaint() ContentfulPaint::ContentfulPaint()
: text_(PageLoadMetricsObserver::LargestContentType::kText), : text_(PageLoadMetricsObserver::LargestContentType::kText),
image_(PageLoadMetricsObserver::LargestContentType::kImage) {} image_(PageLoadMetricsObserver::LargestContentType::kImage) {}
const TimingInfo& ContentfulPaint::MergeTextAndImageTiming() { const ContentfulPaintTimingInfo& ContentfulPaint::MergeTextAndImageTiming() {
return MergeTimingsBySizeAndTime(text_, image_); return MergeTimingsBySizeAndTime(text_, image_);
} }
...@@ -144,10 +147,11 @@ void LargestContentfulPaintHandler::RecordTiming( ...@@ -144,10 +147,11 @@ void LargestContentfulPaintHandler::RecordTiming(
RecordSubframeTiming(timing, navigation_start_offset); RecordSubframeTiming(timing, navigation_start_offset);
} }
const TimingInfo& LargestContentfulPaintHandler::MergeMainFrameAndSubframes() { const ContentfulPaintTimingInfo&
const TimingInfo& main_frame_timing = LargestContentfulPaintHandler::MergeMainFrameAndSubframes() {
const ContentfulPaintTimingInfo& main_frame_timing =
main_frame_contentful_paint_.MergeTextAndImageTiming(); main_frame_contentful_paint_.MergeTextAndImageTiming();
const TimingInfo& subframe_timing = const ContentfulPaintTimingInfo& subframe_timing =
subframe_contentful_paint_.MergeTextAndImageTiming(); subframe_contentful_paint_.MergeTextAndImageTiming();
return MergeTimingsBySizeAndTime(main_frame_timing, subframe_timing); return MergeTimingsBySizeAndTime(main_frame_timing, subframe_timing);
} }
......
...@@ -13,44 +13,34 @@ ...@@ -13,44 +13,34 @@
namespace page_load_metrics { namespace page_load_metrics {
class TimingInfo { class ContentfulPaintTimingInfo {
public: public:
explicit TimingInfo( explicit ContentfulPaintTimingInfo(
page_load_metrics::PageLoadMetricsObserver::LargestContentType); page_load_metrics::PageLoadMetricsObserver::LargestContentType);
explicit TimingInfo( explicit ContentfulPaintTimingInfo(
const base::Optional<base::TimeDelta>&, const base::Optional<base::TimeDelta>&,
const uint64_t& size, const uint64_t& size,
const page_load_metrics::PageLoadMetricsObserver::LargestContentType); const page_load_metrics::PageLoadMetricsObserver::LargestContentType);
explicit TimingInfo(const TimingInfo& other); explicit ContentfulPaintTimingInfo(const ContentfulPaintTimingInfo& other);
void Reset(const base::Optional<base::TimeDelta>&, const uint64_t& size); void Reset(const base::Optional<base::TimeDelta>&, const uint64_t& size);
base::Optional<base::TimeDelta> Time() const { base::Optional<base::TimeDelta> Time() const {
DCHECK(HasConsistentTimeAndSize());
return time_; return time_;
} }
uint64_t Size() const { uint64_t Size() const { return size_; }
DCHECK(HasConsistentTimeAndSize());
return size_;
}
page_load_metrics::PageLoadMetricsObserver::LargestContentType Type() const { page_load_metrics::PageLoadMetricsObserver::LargestContentType Type() const {
DCHECK(HasConsistentTimeAndSize());
return type_; return type_;
} }
bool IsEmpty() const { bool IsEmpty() const {
DCHECK(HasConsistentTimeAndSize()); // |size_| is not necessarily 0, for example, when the largest image is
// |size_| will be 0 as well, as checked by the DCHECK. // still loading.
return !time_; return !time_;
} }
std::unique_ptr<base::trace_event::TracedValue> DataAsTraceValue() const; std::unique_ptr<base::trace_event::TracedValue> DataAsTraceValue() const;
private: private:
TimingInfo() = delete; ContentfulPaintTimingInfo() = delete;
std::string TypeInString() const; std::string TypeInString() const;
// This is only for DCHECK. We will never need the inconsistent state.
bool HasConsistentTimeAndSize() const {
return (time_ && size_) || (!time_ && !size_);
}
// This uses mainthread navigation start as origin.
base::Optional<base::TimeDelta> time_; base::Optional<base::TimeDelta> time_;
uint64_t size_; uint64_t size_;
page_load_metrics::PageLoadMetricsObserver::LargestContentType type_; page_load_metrics::PageLoadMetricsObserver::LargestContentType type_;
...@@ -59,13 +49,13 @@ class TimingInfo { ...@@ -59,13 +49,13 @@ class TimingInfo {
class ContentfulPaint { class ContentfulPaint {
public: public:
ContentfulPaint(); ContentfulPaint();
TimingInfo& Text() { return text_; } ContentfulPaintTimingInfo& Text() { return text_; }
TimingInfo& Image() { return image_; } ContentfulPaintTimingInfo& Image() { return image_; }
const TimingInfo& MergeTextAndImageTiming(); const ContentfulPaintTimingInfo& MergeTextAndImageTiming();
private: private:
TimingInfo text_; ContentfulPaintTimingInfo text_;
TimingInfo image_; ContentfulPaintTimingInfo image_;
}; };
class LargestContentfulPaintHandler { class LargestContentfulPaintHandler {
...@@ -79,7 +69,7 @@ class LargestContentfulPaintHandler { ...@@ -79,7 +69,7 @@ class LargestContentfulPaintHandler {
content::RenderFrameHost* subframe_rfh); content::RenderFrameHost* subframe_rfh);
// We merge the candidates from main frame and subframe to get the largest // We merge the candidates from main frame and subframe to get the largest
// candidate across all frames. // candidate across all frames.
const TimingInfo& MergeMainFrameAndSubframes(); const ContentfulPaintTimingInfo& MergeMainFrameAndSubframes();
void OnDidFinishSubFrameNavigation( void OnDidFinishSubFrameNavigation(
content::NavigationHandle* navigation_handle, content::NavigationHandle* navigation_handle,
const page_load_metrics::PageLoadExtraInfo& extra_info); const page_load_metrics::PageLoadExtraInfo& extra_info);
......
...@@ -303,7 +303,7 @@ void UkmPageLoadMetricsObserver::RecordTimingMetrics( ...@@ -303,7 +303,7 @@ void UkmPageLoadMetricsObserver::RecordTimingMetrics(
builder.SetExperimental_PaintTiming_NavigationToLargestContentPaint( builder.SetExperimental_PaintTiming_NavigationToLargestContentPaint(
largest_content_paint_time.value().InMilliseconds()); largest_content_paint_time.value().InMilliseconds());
} }
const page_load_metrics::TimingInfo& paint = const page_load_metrics::ContentfulPaintTimingInfo& paint =
largest_contentful_paint_handler_.MergeMainFrameAndSubframes(); largest_contentful_paint_handler_.MergeMainFrameAndSubframes();
if (!paint.IsEmpty() && if (!paint.IsEmpty() &&
WasStartedInForegroundOptionalEventInForeground(paint.Time(), info)) { WasStartedInForegroundOptionalEventInForeground(paint.Time(), info)) {
......
...@@ -337,17 +337,19 @@ mojom::PageLoadTimingPtr MetricsRenderFrameObserver::GetTiming() const { ...@@ -337,17 +337,19 @@ mojom::PageLoadTimingPtr MetricsRenderFrameObserver::GetTiming() const {
timing->paint_timing->first_meaningful_paint = timing->paint_timing->first_meaningful_paint =
ClampDelta(perf.FirstMeaningfulPaint(), start); ClampDelta(perf.FirstMeaningfulPaint(), start);
} }
if (perf.LargestImagePaint() > 0.0) { if (perf.LargestImagePaintSize() > 0) {
timing->paint_timing->largest_image_paint = timing->paint_timing->largest_image_paint =
ClampDelta(perf.LargestImagePaint(), start); perf.LargestImagePaint() == 0.0
DCHECK(perf.LargestImagePaintSize() > 0); ? base::TimeDelta()
: ClampDelta(perf.LargestImagePaint(), start);
timing->paint_timing->largest_image_paint_size = timing->paint_timing->largest_image_paint_size =
perf.LargestImagePaintSize(); perf.LargestImagePaintSize();
} }
if (perf.LargestTextPaint() > 0.0) { if (perf.LargestTextPaintSize() > 0) {
timing->paint_timing->largest_text_paint = timing->paint_timing->largest_text_paint =
ClampDelta(perf.LargestTextPaint(), start); perf.LargestTextPaint() == 0.0
DCHECK(perf.LargestTextPaintSize() > 0); ? base::TimeDelta()
: ClampDelta(perf.LargestTextPaint(), start);
timing->paint_timing->largest_text_paint_size = perf.LargestTextPaintSize(); timing->paint_timing->largest_text_paint_size = perf.LargestTextPaintSize();
} }
if (perf.ParseStart() > 0.0) if (perf.ParseStart() > 0.0)
......
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