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 {
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
// associated frame changed.
interface PageLoadMetrics {
......
......@@ -18,8 +18,10 @@ void FakePageTimingSender::SendTiming(
const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata,
mojom::PageLoadFeaturesPtr new_features,
std::vector<mojom::ResourceDataUpdatePtr> resources) {
validator_->UpdateTiming(timing, metadata, new_features, resources);
std::vector<mojom::ResourceDataUpdatePtr> resources,
const mojom::PageRenderData& render_data) {
validator_->UpdateTiming(timing, metadata, new_features, resources,
render_data);
}
FakePageTimingSender::PageTimingValidator::PageTimingValidator() {}
......@@ -91,11 +93,18 @@ void FakePageTimingSender::PageTimingValidator::VerifyExpectedCssProperties()
<< "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(
const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata,
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());
for (const auto feature : new_features->features) {
EXPECT_EQ(actual_features_.find(feature), actual_features_.end())
......@@ -109,9 +118,11 @@ void FakePageTimingSender::PageTimingValidator::UpdateTiming(
<< "has been sent more than once";
actual_css_properties_.insert(css_property_id);
}
actual_render_data_.layout_jank_score = render_data.layout_jank_score;
VerifyExpectedTimings();
VerifyExpectedFeatures();
VerifyExpectedCssProperties();
VerifyExpectedRenderData();
}
} // namespace page_load_metrics
......@@ -54,12 +54,17 @@ class FakePageTimingSender : public PageTimingSender {
// should be passed via UpdateExpectedPageLoadCSSProperties.
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
// expected features provided via ExpectPageLoadFeatures.
void VerifyExpectedFeatures() const;
// Forces verification that actual CSS properties sent through SendTiming
// match expected CSS properties provided via ExpectPageLoadCSSProperties.
void VerifyExpectedCssProperties() const;
void VerifyExpectedRenderData() const;
const std::vector<mojom::PageLoadTimingPtr>& expected_timings() const {
return expected_timings_;
......@@ -72,7 +77,8 @@ class FakePageTimingSender : public PageTimingSender {
const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata,
const mojom::PageLoadFeaturesPtr& new_features,
const std::vector<mojom::ResourceDataUpdatePtr>& resources);
const std::vector<mojom::ResourceDataUpdatePtr>& resources,
const mojom::PageRenderData& render_data);
private:
std::vector<mojom::PageLoadTimingPtr> expected_timings_;
......@@ -81,6 +87,8 @@ class FakePageTimingSender : public PageTimingSender {
std::set<blink::mojom::WebFeature> actual_features_;
std::set<int> expected_css_properties_;
std::set<int> actual_css_properties_;
mojom::PageRenderData expected_render_data_;
mojom::PageRenderData actual_render_data_;
DISALLOW_COPY_AND_ASSIGN(PageTimingValidator);
};
......@@ -89,7 +97,8 @@ class FakePageTimingSender : public PageTimingSender {
void SendTiming(const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata,
mojom::PageLoadFeaturesPtr new_features,
std::vector<mojom::ResourceDataUpdatePtr> resources) override;
std::vector<mojom::ResourceDataUpdatePtr> resources,
const mojom::PageRenderData& render_data) override;
private:
PageTimingValidator* const validator_;
......
......@@ -38,12 +38,13 @@ class MojoPageTimingSender : public PageTimingSender {
&page_load_metrics_);
}
~MojoPageTimingSender() override {}
void SendTiming(
const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata,
mojom::PageLoadFeaturesPtr new_features,
std::vector<mojom::ResourceDataUpdatePtr> resources) override {
void SendTiming(const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata,
mojom::PageLoadFeaturesPtr new_features,
std::vector<mojom::ResourceDataUpdatePtr> resources,
const mojom::PageRenderData& render_data) override {
DCHECK(page_load_metrics_);
// TODO: Include render_data in IPC.
page_load_metrics_->UpdateTiming(timing->Clone(), metadata->Clone(),
std::move(new_features),
std::move(resources));
......@@ -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(
int request_id,
const network::ResourceResponseHead& response_head,
......
......@@ -44,6 +44,7 @@ class MetricsRenderFrameObserver
void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) override;
void DidObserveNewCssPropertyUsage(int css_property,
bool is_animated) override;
void DidObserveLayoutJank(double jank_fraction) override;
void DidStartResponse(int request_id,
const network::ResourceResponseHead& response_head,
content::ResourceType resource_type) override;
......
......@@ -35,6 +35,7 @@ PageTimingMetricsSender::PageTimingMetricsSender(
last_timing_(std::move(initial_timing)),
metadata_(mojom::PageLoadMetadata::New()),
new_features_(mojom::PageLoadFeatures::New()),
render_data_(),
buffer_timer_delay_ms_(kBufferTimerDelayMillis) {
page_resource_data_use_.emplace(
std::piecewise_construct,
......@@ -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(
int resource_id,
const network::ResourceResponseHead& response_head) {
......@@ -200,7 +207,7 @@ void PageTimingMetricsSender::SendNow() {
}
}
sender_->SendTiming(last_timing_, metadata_, std::move(new_features_),
std::move(resources));
std::move(resources), render_data_);
new_features_ = mojom::PageLoadFeatures::New();
modified_resources_.clear();
}
......
......@@ -44,6 +44,7 @@ class PageTimingMetricsSender {
void DidObserveLoadingBehavior(blink::WebLoadingBehaviorFlag behavior);
void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature);
void DidObserveNewCssPropertyUsage(int css_property, bool is_animated);
void DidObserveLayoutJank(double jank_fraction);
void DidStartResponse(int resource_id,
const network::ResourceResponseHead& response_head);
void DidReceiveTransferSizeUpdate(int resource_id, int received_data_length);
......@@ -75,6 +76,7 @@ class PageTimingMetricsSender {
// A list of newly observed features during page load, to be sent to the
// browser.
mojom::PageLoadFeaturesPtr new_features_;
mojom::PageRenderData render_data_;
std::bitset<static_cast<size_t>(blink::mojom::WebFeature::kNumberOfFeatures)>
features_sent_;
......
......@@ -340,4 +340,26 @@ TEST_F(PageTimingMetricsSenderTest, SendMultipleCssPropertiesTwice) {
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
......@@ -14,11 +14,11 @@ namespace page_load_metrics {
class PageTimingSender {
public:
virtual ~PageTimingSender() {}
virtual void SendTiming(
const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata,
mojom::PageLoadFeaturesPtr new_features,
std::vector<mojom::ResourceDataUpdatePtr> resources) = 0;
virtual void SendTiming(const mojom::PageLoadTimingPtr& timing,
const mojom::PageLoadMetadataPtr& metadata,
mojom::PageLoadFeaturesPtr new_features,
std::vector<mojom::ResourceDataUpdatePtr> resources,
const mojom::PageRenderData& render_data) = 0;
};
} // namespace page_load_metrics
......
......@@ -133,6 +133,12 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
virtual void DidObserveNewCssPropertyUsage(int css_property,
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.
// Complete or Cancel is guaranteed to be called for a response that started.
// |request_id| uniquely identifies the request within this render frame.
......
......@@ -5230,6 +5230,11 @@ void RenderFrameImpl::DidObserveNewCssPropertyUsage(int css_property,
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) {
return GetContentClient()->renderer()->ShouldTrackUseCounter(url);
}
......
......@@ -727,6 +727,7 @@ class CONTENT_EXPORT RenderFrameImpl
void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) override;
void DidObserveNewCssPropertyUsage(int css_property,
bool is_animated) override;
void DidObserveLayoutJank(double jank_fraction) override;
bool ShouldTrackUseCounter(const blink::WebURL& url) override;
void DidCreateScriptContext(v8::Local<v8::Context> context,
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