Commit 9f9b8e7e authored by Steve Kobes's avatar Steve Kobes Committed by Commit Bot

Track layout jank score in PageTimingMetricsSender.

Bug: 581518
Change-Id: Ibc9c4948d924e106e3da60408e401875217a47f9
Reviewed-on: https://chromium-review.googlesource.com/c/1291215
Commit-Queue: Steve Kobes <skobes@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarBryan McQuade <bmcquade@chromium.org>
Cr-Commit-Position: refs/heads/master@{#603123}
parent 090f1f05
...@@ -200,6 +200,12 @@ struct ResourceDataUpdate { ...@@ -200,6 +200,12 @@ struct ResourceDataUpdate {
string mime_type; string mime_type;
}; };
// Metrics about how the page rendered during the browsing session.
struct PageRenderData {
// How much visible elements in the frame shifted (bit.ly/lsm-explainer).
float layout_jank_score;
};
// Sent from renderer to browser process when the PageLoadTiming for the // Sent from renderer to browser process when the PageLoadTiming for the
// associated frame changed. // associated frame changed.
interface PageLoadMetrics { interface PageLoadMetrics {
......
...@@ -18,8 +18,10 @@ void FakePageTimingSender::SendTiming( ...@@ -18,8 +18,10 @@ void FakePageTimingSender::SendTiming(
const mojom::PageLoadTimingPtr& timing, const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata, const mojom::PageLoadMetadataPtr& metadata,
mojom::PageLoadFeaturesPtr new_features, mojom::PageLoadFeaturesPtr new_features,
std::vector<mojom::ResourceDataUpdatePtr> resources) { std::vector<mojom::ResourceDataUpdatePtr> resources,
validator_->UpdateTiming(timing, metadata, new_features, resources); const mojom::PageRenderData& render_data) {
validator_->UpdateTiming(timing, metadata, new_features, resources,
render_data);
} }
FakePageTimingSender::PageTimingValidator::PageTimingValidator() {} FakePageTimingSender::PageTimingValidator::PageTimingValidator() {}
...@@ -91,11 +93,18 @@ void FakePageTimingSender::PageTimingValidator::VerifyExpectedCssProperties() ...@@ -91,11 +93,18 @@ void FakePageTimingSender::PageTimingValidator::VerifyExpectedCssProperties()
<< "More CSS Properties are actually observed than expected"; << "More CSS Properties are actually observed than expected";
} }
void FakePageTimingSender::PageTimingValidator::VerifyExpectedRenderData()
const {
EXPECT_FLOAT_EQ(expected_render_data_.layout_jank_score,
actual_render_data_.layout_jank_score);
}
void FakePageTimingSender::PageTimingValidator::UpdateTiming( void FakePageTimingSender::PageTimingValidator::UpdateTiming(
const mojom::PageLoadTimingPtr& timing, const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata, const mojom::PageLoadMetadataPtr& metadata,
const mojom::PageLoadFeaturesPtr& new_features, const mojom::PageLoadFeaturesPtr& new_features,
const std::vector<mojom::ResourceDataUpdatePtr>& resources) { const std::vector<mojom::ResourceDataUpdatePtr>& resources,
const mojom::PageRenderData& render_data) {
actual_timings_.push_back(timing.Clone()); actual_timings_.push_back(timing.Clone());
for (const auto feature : new_features->features) { for (const auto feature : new_features->features) {
EXPECT_EQ(actual_features_.find(feature), actual_features_.end()) EXPECT_EQ(actual_features_.find(feature), actual_features_.end())
...@@ -109,9 +118,11 @@ void FakePageTimingSender::PageTimingValidator::UpdateTiming( ...@@ -109,9 +118,11 @@ void FakePageTimingSender::PageTimingValidator::UpdateTiming(
<< "has been sent more than once"; << "has been sent more than once";
actual_css_properties_.insert(css_property_id); actual_css_properties_.insert(css_property_id);
} }
actual_render_data_.layout_jank_score = render_data.layout_jank_score;
VerifyExpectedTimings(); VerifyExpectedTimings();
VerifyExpectedFeatures(); VerifyExpectedFeatures();
VerifyExpectedCssProperties(); VerifyExpectedCssProperties();
VerifyExpectedRenderData();
} }
} // namespace page_load_metrics } // namespace page_load_metrics
...@@ -54,12 +54,17 @@ class FakePageTimingSender : public PageTimingSender { ...@@ -54,12 +54,17 @@ class FakePageTimingSender : public PageTimingSender {
// should be passed via UpdateExpectedPageLoadCSSProperties. // should be passed via UpdateExpectedPageLoadCSSProperties.
void UpdateExpectPageLoadCssProperties(int css_property_id); void UpdateExpectPageLoadCssProperties(int css_property_id);
void UpdateExpectPageRenderData(const mojom::PageRenderData& render_data) {
expected_render_data_ = render_data;
}
// Forces verification that actual features sent through SendTiming match // Forces verification that actual features sent through SendTiming match
// expected features provided via ExpectPageLoadFeatures. // expected features provided via ExpectPageLoadFeatures.
void VerifyExpectedFeatures() const; void VerifyExpectedFeatures() const;
// Forces verification that actual CSS properties sent through SendTiming // Forces verification that actual CSS properties sent through SendTiming
// match expected CSS properties provided via ExpectPageLoadCSSProperties. // match expected CSS properties provided via ExpectPageLoadCSSProperties.
void VerifyExpectedCssProperties() const; void VerifyExpectedCssProperties() const;
void VerifyExpectedRenderData() const;
const std::vector<mojom::PageLoadTimingPtr>& expected_timings() const { const std::vector<mojom::PageLoadTimingPtr>& expected_timings() const {
return expected_timings_; return expected_timings_;
...@@ -72,7 +77,8 @@ class FakePageTimingSender : public PageTimingSender { ...@@ -72,7 +77,8 @@ class FakePageTimingSender : public PageTimingSender {
const mojom::PageLoadTimingPtr& timing, const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata, const mojom::PageLoadMetadataPtr& metadata,
const mojom::PageLoadFeaturesPtr& new_features, const mojom::PageLoadFeaturesPtr& new_features,
const std::vector<mojom::ResourceDataUpdatePtr>& resources); const std::vector<mojom::ResourceDataUpdatePtr>& resources,
const mojom::PageRenderData& render_data);
private: private:
std::vector<mojom::PageLoadTimingPtr> expected_timings_; std::vector<mojom::PageLoadTimingPtr> expected_timings_;
...@@ -81,6 +87,8 @@ class FakePageTimingSender : public PageTimingSender { ...@@ -81,6 +87,8 @@ class FakePageTimingSender : public PageTimingSender {
std::set<blink::mojom::WebFeature> actual_features_; std::set<blink::mojom::WebFeature> actual_features_;
std::set<int> expected_css_properties_; std::set<int> expected_css_properties_;
std::set<int> actual_css_properties_; std::set<int> actual_css_properties_;
mojom::PageRenderData expected_render_data_;
mojom::PageRenderData actual_render_data_;
DISALLOW_COPY_AND_ASSIGN(PageTimingValidator); DISALLOW_COPY_AND_ASSIGN(PageTimingValidator);
}; };
...@@ -89,7 +97,8 @@ class FakePageTimingSender : public PageTimingSender { ...@@ -89,7 +97,8 @@ class FakePageTimingSender : public PageTimingSender {
void SendTiming(const mojom::PageLoadTimingPtr& timing, void SendTiming(const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata, const mojom::PageLoadMetadataPtr& metadata,
mojom::PageLoadFeaturesPtr new_features, mojom::PageLoadFeaturesPtr new_features,
std::vector<mojom::ResourceDataUpdatePtr> resources) override; std::vector<mojom::ResourceDataUpdatePtr> resources,
const mojom::PageRenderData& render_data) override;
private: private:
PageTimingValidator* const validator_; PageTimingValidator* const validator_;
......
...@@ -38,12 +38,13 @@ class MojoPageTimingSender : public PageTimingSender { ...@@ -38,12 +38,13 @@ class MojoPageTimingSender : public PageTimingSender {
&page_load_metrics_); &page_load_metrics_);
} }
~MojoPageTimingSender() override {} ~MojoPageTimingSender() override {}
void SendTiming( void SendTiming(const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadTimingPtr& timing, const mojom::PageLoadMetadataPtr& metadata,
const mojom::PageLoadMetadataPtr& metadata, mojom::PageLoadFeaturesPtr new_features,
mojom::PageLoadFeaturesPtr new_features, std::vector<mojom::ResourceDataUpdatePtr> resources,
std::vector<mojom::ResourceDataUpdatePtr> resources) override { const mojom::PageRenderData& render_data) override {
DCHECK(page_load_metrics_); DCHECK(page_load_metrics_);
// TODO: Include render_data in IPC.
page_load_metrics_->UpdateTiming(timing->Clone(), metadata->Clone(), page_load_metrics_->UpdateTiming(timing->Clone(), metadata->Clone(),
std::move(new_features), std::move(new_features),
std::move(resources)); std::move(resources));
...@@ -89,6 +90,11 @@ void MetricsRenderFrameObserver::DidObserveNewCssPropertyUsage( ...@@ -89,6 +90,11 @@ void MetricsRenderFrameObserver::DidObserveNewCssPropertyUsage(
} }
} }
void MetricsRenderFrameObserver::DidObserveLayoutJank(double jank_fraction) {
if (page_timing_metrics_sender_)
page_timing_metrics_sender_->DidObserveLayoutJank(jank_fraction);
}
void MetricsRenderFrameObserver::DidStartResponse( void MetricsRenderFrameObserver::DidStartResponse(
int request_id, int request_id,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& response_head,
......
...@@ -44,6 +44,7 @@ class MetricsRenderFrameObserver ...@@ -44,6 +44,7 @@ class MetricsRenderFrameObserver
void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) override; void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) override;
void DidObserveNewCssPropertyUsage(int css_property, void DidObserveNewCssPropertyUsage(int css_property,
bool is_animated) override; bool is_animated) override;
void DidObserveLayoutJank(double jank_fraction) override;
void DidStartResponse(int request_id, void DidStartResponse(int request_id,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& response_head,
content::ResourceType resource_type) override; content::ResourceType resource_type) override;
......
...@@ -35,6 +35,7 @@ PageTimingMetricsSender::PageTimingMetricsSender( ...@@ -35,6 +35,7 @@ PageTimingMetricsSender::PageTimingMetricsSender(
last_timing_(std::move(initial_timing)), last_timing_(std::move(initial_timing)),
metadata_(mojom::PageLoadMetadata::New()), metadata_(mojom::PageLoadMetadata::New()),
new_features_(mojom::PageLoadFeatures::New()), new_features_(mojom::PageLoadFeatures::New()),
render_data_(),
buffer_timer_delay_ms_(kBufferTimerDelayMillis) { buffer_timer_delay_ms_(kBufferTimerDelayMillis) {
page_resource_data_use_.emplace( page_resource_data_use_.emplace(
std::piecewise_construct, std::piecewise_construct,
...@@ -90,6 +91,12 @@ void PageTimingMetricsSender::DidObserveNewCssPropertyUsage(int css_property, ...@@ -90,6 +91,12 @@ void PageTimingMetricsSender::DidObserveNewCssPropertyUsage(int css_property,
} }
} }
void PageTimingMetricsSender::DidObserveLayoutJank(double jank_fraction) {
DCHECK(jank_fraction > 0);
render_data_.layout_jank_score += jank_fraction;
EnsureSendTimer();
}
void PageTimingMetricsSender::DidStartResponse( void PageTimingMetricsSender::DidStartResponse(
int resource_id, int resource_id,
const network::ResourceResponseHead& response_head) { const network::ResourceResponseHead& response_head) {
...@@ -200,7 +207,7 @@ void PageTimingMetricsSender::SendNow() { ...@@ -200,7 +207,7 @@ void PageTimingMetricsSender::SendNow() {
} }
} }
sender_->SendTiming(last_timing_, metadata_, std::move(new_features_), sender_->SendTiming(last_timing_, metadata_, std::move(new_features_),
std::move(resources)); std::move(resources), render_data_);
new_features_ = mojom::PageLoadFeatures::New(); new_features_ = mojom::PageLoadFeatures::New();
modified_resources_.clear(); modified_resources_.clear();
} }
......
...@@ -44,6 +44,7 @@ class PageTimingMetricsSender { ...@@ -44,6 +44,7 @@ class PageTimingMetricsSender {
void DidObserveLoadingBehavior(blink::WebLoadingBehaviorFlag behavior); void DidObserveLoadingBehavior(blink::WebLoadingBehaviorFlag behavior);
void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature); void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature);
void DidObserveNewCssPropertyUsage(int css_property, bool is_animated); void DidObserveNewCssPropertyUsage(int css_property, bool is_animated);
void DidObserveLayoutJank(double jank_fraction);
void DidStartResponse(int resource_id, void DidStartResponse(int resource_id,
const network::ResourceResponseHead& response_head); const network::ResourceResponseHead& response_head);
void DidReceiveTransferSizeUpdate(int resource_id, int received_data_length); void DidReceiveTransferSizeUpdate(int resource_id, int received_data_length);
...@@ -75,6 +76,7 @@ class PageTimingMetricsSender { ...@@ -75,6 +76,7 @@ class PageTimingMetricsSender {
// A list of newly observed features during page load, to be sent to the // A list of newly observed features during page load, to be sent to the
// browser. // browser.
mojom::PageLoadFeaturesPtr new_features_; mojom::PageLoadFeaturesPtr new_features_;
mojom::PageRenderData render_data_;
std::bitset<static_cast<size_t>(blink::mojom::WebFeature::kNumberOfFeatures)> std::bitset<static_cast<size_t>(blink::mojom::WebFeature::kNumberOfFeatures)>
features_sent_; features_sent_;
......
...@@ -340,4 +340,26 @@ TEST_F(PageTimingMetricsSenderTest, SendMultipleCssPropertiesTwice) { ...@@ -340,4 +340,26 @@ TEST_F(PageTimingMetricsSenderTest, SendMultipleCssPropertiesTwice) {
validator_.VerifyExpectedFeatures(); validator_.VerifyExpectedFeatures();
} }
TEST_F(PageTimingMetricsSenderTest, SendPageRenderData) {
mojom::PageLoadTiming timing;
InitPageLoadTimingForTest(&timing);
// We need to send the PageLoadTiming here even though it is not really
// related to the PageRenderData. This is because metrics_sender_ sends
// its last_timing_ when the mock timer fires, causing the validator to
// look for a matching expectation.
metrics_sender_->Send(timing.Clone());
validator_.ExpectPageLoadTiming(timing);
metrics_sender_->DidObserveLayoutJank(0.5);
metrics_sender_->DidObserveLayoutJank(0.5);
metrics_sender_->DidObserveLayoutJank(0.5);
mojom::PageRenderData render_data(1.5);
validator_.UpdateExpectPageRenderData(render_data);
metrics_sender_->mock_timer()->Fire();
validator_.VerifyExpectedRenderData();
}
} // namespace page_load_metrics } // namespace page_load_metrics
...@@ -14,11 +14,11 @@ namespace page_load_metrics { ...@@ -14,11 +14,11 @@ namespace page_load_metrics {
class PageTimingSender { class PageTimingSender {
public: public:
virtual ~PageTimingSender() {} virtual ~PageTimingSender() {}
virtual void SendTiming( virtual void SendTiming(const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadTimingPtr& timing, const mojom::PageLoadMetadataPtr& metadata,
const mojom::PageLoadMetadataPtr& metadata, mojom::PageLoadFeaturesPtr new_features,
mojom::PageLoadFeaturesPtr new_features, std::vector<mojom::ResourceDataUpdatePtr> resources,
std::vector<mojom::ResourceDataUpdatePtr> resources) = 0; const mojom::PageRenderData& render_data) = 0;
}; };
} // namespace page_load_metrics } // namespace page_load_metrics
......
...@@ -133,6 +133,12 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener, ...@@ -133,6 +133,12 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
virtual void DidObserveNewCssPropertyUsage(int css_property, virtual void DidObserveNewCssPropertyUsage(int css_property,
bool is_animated) {} bool is_animated) {}
// Reports that visible elements in the frame shifted (bit.ly/lsm-explainer).
// This is called once for each janking animation frame, with the jank
// fraction for that frame. The cumulative jank score can be inferred by
// summing the jank fractions.
virtual void DidObserveLayoutJank(double jank_fraction) {}
// Notification when the renderer a response started, completed or canceled. // Notification when the renderer a response started, completed or canceled.
// Complete or Cancel is guaranteed to be called for a response that started. // Complete or Cancel is guaranteed to be called for a response that started.
// |request_id| uniquely identifies the request within this render frame. // |request_id| uniquely identifies the request within this render frame.
......
...@@ -5230,6 +5230,11 @@ void RenderFrameImpl::DidObserveNewCssPropertyUsage(int css_property, ...@@ -5230,6 +5230,11 @@ void RenderFrameImpl::DidObserveNewCssPropertyUsage(int css_property,
observer.DidObserveNewCssPropertyUsage(css_property, is_animated); observer.DidObserveNewCssPropertyUsage(css_property, is_animated);
} }
void RenderFrameImpl::DidObserveLayoutJank(double jank_fraction) {
for (auto& observer : observers_)
observer.DidObserveLayoutJank(jank_fraction);
}
bool RenderFrameImpl::ShouldTrackUseCounter(const blink::WebURL& url) { bool RenderFrameImpl::ShouldTrackUseCounter(const blink::WebURL& url) {
return GetContentClient()->renderer()->ShouldTrackUseCounter(url); return GetContentClient()->renderer()->ShouldTrackUseCounter(url);
} }
......
...@@ -727,6 +727,7 @@ class CONTENT_EXPORT RenderFrameImpl ...@@ -727,6 +727,7 @@ class CONTENT_EXPORT RenderFrameImpl
void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) override; void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) override;
void DidObserveNewCssPropertyUsage(int css_property, void DidObserveNewCssPropertyUsage(int css_property,
bool is_animated) override; bool is_animated) override;
void DidObserveLayoutJank(double jank_fraction) override;
bool ShouldTrackUseCounter(const blink::WebURL& url) override; bool ShouldTrackUseCounter(const blink::WebURL& url) override;
void DidCreateScriptContext(v8::Local<v8::Context> context, void DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) override; int world_id) override;
......
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