Commit 47b6d831 authored by Farah Charab's avatar Farah Charab Committed by Commit Bot

Scheduler: Experiment with different priorities for ad frames.

Set priority of ad frames to low or best effort depending on the
feature list enabled.

Bug: 856150
Change-Id: Ia76d55e1fc4b8617d5db9bca26b79ac25b5856c9
Reviewed-on: https://chromium-review.googlesource.com/1112251Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarRobert Kaplow <rkaplow@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Reviewed-by: default avatarAlex Clarke <alexclarke@chromium.org>
Commit-Queue: Farah Charab <farahcharab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#571103}
parent b4a8afc7
......@@ -19,6 +19,26 @@
]
}
],
"AdFramePriority": [
{
"platforms": [
"win",
"mac",
"chromeos",
"linux",
"ios",
"android"
],
"experiments": [
{
"name": "LowPriorityAdFrameEnabled",
"enable_features": [
"BlinkSchedulerLowPriorityForAdFrame"
]
}
]
}
],
"AllowClientHintsToThirdParty": [
{
"platforms": [
......
......@@ -155,6 +155,8 @@ class EmptyFrameScheduler final : public FrameScheduler {
void SetPaused(bool) override {}
void SetCrossOrigin(bool) override {}
bool IsCrossOrigin() const override { return false; }
void SetIsAdFrame() override {}
bool IsAdFrame() const override { return false; }
void TraceUrlChange(const String& override) override {}
FrameScheduler::FrameType GetFrameType() const override {
return FrameScheduler::FrameType::kSubframe;
......
......@@ -46,6 +46,7 @@
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/instance_counters.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/supplementable.h"
namespace base {
......@@ -72,7 +73,7 @@ class FetchParameters;
class FloatSize;
class FrameConsole;
class FrameResourceCoordinator;
class FrameScheduler;
// class FrameScheduler;
class FrameSelection;
class InputMethodController;
class InspectorTraceEvents;
......@@ -343,6 +344,7 @@ class CORE_EXPORT LocalFrame final : public Frame,
if (is_ad_subframe_)
return;
is_ad_subframe_ = true;
frame_scheduler_->SetIsAdFrame();
InstanceCounters::IncrementCounter(InstanceCounters::kAdSubframeCounter);
}
......@@ -356,10 +358,7 @@ class CORE_EXPORT LocalFrame final : public Frame,
private:
friend class FrameNavigationDisabler;
LocalFrame(LocalFrameClient*,
Page&,
FrameOwner*,
InterfaceRegistry*);
LocalFrame(LocalFrameClient*, Page&, FrameOwner*, InterfaceRegistry*);
// Intentionally private to prevent redundant checks when the type is
// already LocalFrame.
......
......@@ -82,6 +82,15 @@ const base::Feature kLowPriorityForHiddenFrame{
"BlinkSchedulerLowPriorityForHiddenFrame",
base::FEATURE_DISABLED_BY_DEFAULT};
// Enables setting the priority of an ad frame to low priority.
const base::Feature kLowPriorityForAdFrame{
"BlinkSchedulerLowPriorityForAdFrame", base::FEATURE_DISABLED_BY_DEFAULT};
// Enables setting the priority of an ad frame to best effort priority.
const base::Feature kBestEffortPriorityForAdFrame{
"BlinkSchedulerBestEffortPriorityForAdFrame",
base::FEATURE_DISABLED_BY_DEFAULT};
// Enables a chosen experiments only during the load use case.
const base::Feature kExperimentOnlyWhenLoading{
"BlinkSchedulerExperimentOnlyWhenLoading",
......
......@@ -117,6 +117,7 @@ FrameSchedulerImpl::FrameSchedulerImpl(
base::trace_event::BlameContext* blame_context,
FrameScheduler::FrameType frame_type)
: frame_type_(frame_type),
is_ad_frame_(false),
main_thread_scheduler_(main_thread_scheduler),
parent_page_scheduler_(parent_page_scheduler),
blame_context_(blame_context),
......@@ -267,6 +268,15 @@ void FrameSchedulerImpl::SetCrossOrigin(bool cross_origin) {
UpdatePolicy();
}
void FrameSchedulerImpl::SetIsAdFrame() {
is_ad_frame_ = true;
UpdateQueuePriorities();
}
bool FrameSchedulerImpl::IsAdFrame() const {
return is_ad_frame_;
}
bool FrameSchedulerImpl::IsCrossOrigin() const {
return frame_origin_type_ == FrameOriginType::kCrossOriginFrame;
}
......@@ -755,6 +765,16 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
.low_priority_throttleable &&
is_throttleable_task_queue)
return TaskQueue::QueuePriority::kLowPriority;
if (main_thread_scheduler_->scheduling_settings().low_priority_ad_frame &&
IsAdFrame()) {
return TaskQueue::QueuePriority::kLowPriority;
}
if (main_thread_scheduler_->scheduling_settings().best_effort_ad_frame &&
IsAdFrame()) {
return TaskQueue::QueuePriority::kBestEffortPriority;
}
}
// TODO(farahcharab) Change highest priority to high priority for frame
......
......@@ -68,6 +68,10 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
void SetCrossOrigin(bool cross_origin) override;
bool IsCrossOrigin() const override;
void SetIsAdFrame() override;
bool IsAdFrame() const override;
void TraceUrlChange(const String& url) override;
FrameScheduler::FrameType GetFrameType() const override;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) override;
......@@ -178,6 +182,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
const FrameScheduler::FrameType frame_type_;
bool is_ad_frame_;
TraceableVariableController tracing_controller_;
scoped_refptr<MainThreadTaskQueue> loading_task_queue_;
scoped_refptr<MainThreadTaskQueue> loading_control_task_queue_;
......
......@@ -1138,6 +1138,187 @@ TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,
TaskQueue::QueuePriority::kNormalPriority);
}
class LowPriorityAdFrameExperimentTest : public FrameSchedulerImplTest {
public:
LowPriorityAdFrameExperimentTest()
: FrameSchedulerImplTest({kLowPriorityForAdFrame}, {}) {}
};
TEST_F(LowPriorityAdFrameExperimentTest, FrameQueuesPriorities) {
EXPECT_FALSE(frame_scheduler_->IsAdFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
frame_scheduler_->SetIsAdFrame();
EXPECT_TRUE(frame_scheduler_->IsAdFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
}
class LowPriorityAdFrameDuringLoadingExperimentTest
: public FrameSchedulerImplTest {
public:
LowPriorityAdFrameDuringLoadingExperimentTest()
: FrameSchedulerImplTest(
{kLowPriorityForAdFrame, kExperimentOnlyWhenLoading},
{}) {}
};
TEST_F(LowPriorityAdFrameDuringLoadingExperimentTest, FrameQueuesPriorities) {
frame_scheduler_->SetIsAdFrame();
EXPECT_TRUE(frame_scheduler_->IsAdFrame());
// Main thread scheduler is in the loading use case.
scheduler_->DidStartProvisionalLoad(true);
EXPECT_TRUE(page_scheduler_->IsLoading());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
// Main thread scheduler is no longer in loading use case.
scheduler_->OnFirstMeaningfulPaint();
EXPECT_FALSE(page_scheduler_->IsLoading());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
}
class BestEffortPriorityAdFrameExperimentTest : public FrameSchedulerImplTest {
public:
BestEffortPriorityAdFrameExperimentTest()
: FrameSchedulerImplTest({kBestEffortPriorityForAdFrame}, {}) {}
};
TEST_F(BestEffortPriorityAdFrameExperimentTest, FrameQueuesPriorities) {
EXPECT_FALSE(frame_scheduler_->IsAdFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
frame_scheduler_->SetIsAdFrame();
EXPECT_TRUE(frame_scheduler_->IsAdFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
}
class BestEffortPriorityAdFrameDuringLoadingExperimentTest
: public FrameSchedulerImplTest {
public:
BestEffortPriorityAdFrameDuringLoadingExperimentTest()
: FrameSchedulerImplTest(
{kBestEffortPriorityForAdFrame, kExperimentOnlyWhenLoading},
{}) {}
};
TEST_F(BestEffortPriorityAdFrameDuringLoadingExperimentTest,
FrameQueuesPriorities) {
frame_scheduler_->SetIsAdFrame();
EXPECT_TRUE(frame_scheduler_->IsAdFrame());
// Main thread scheduler is in the loading use case.
scheduler_->DidStartProvisionalLoad(true);
EXPECT_TRUE(page_scheduler_->IsLoading());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
// Main thread scheduler is no longer in loading use case.
scheduler_->OnFirstMeaningfulPaint();
EXPECT_FALSE(page_scheduler_->IsLoading());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
}
} // namespace frame_scheduler_impl_unittest
} // namespace scheduler
} // namespace blink
......@@ -651,6 +651,10 @@ MainThreadSchedulerImpl::SchedulingSettings::SchedulingSettings() {
low_priority_subframe_throttleable =
base::FeatureList::IsEnabled(kLowPriorityForSubFrameThrottleableTask);
low_priority_ad_frame = base::FeatureList::IsEnabled(kLowPriorityForAdFrame);
best_effort_ad_frame =
base::FeatureList::IsEnabled(kBestEffortPriorityForAdFrame);
experiment_only_when_loading =
base::FeatureList::IsEnabled(kExperimentOnlyWhenLoading);
}
......
......@@ -90,16 +90,20 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// High priority input experiment.
bool high_priority_input;
// Background page priority experiment.
// Background page priority experiment (crbug.com/848835).
bool low_priority_background_page;
bool best_effort_background_page;
// Task and subframe priority experiment.
// Task and subframe priority experiment (crbug.com/852380)
bool low_priority_subframe;
bool low_priority_throttleable;
bool low_priority_subframe_throttleable;
bool low_priority_hidden_frame;
// Ads priority experiment (crbug.com/856150)
bool low_priority_ad_frame;
bool best_effort_ad_frame;
// Turn on relevant experiments during the loading phase.
bool experiment_only_when_loading;
};
......
......@@ -49,6 +49,10 @@ class FrameScheduler : public FrameOrWorkerScheduler {
// frames.
virtual void SetCrossOrigin(bool) = 0;
virtual bool IsCrossOrigin() const = 0;
virtual void SetIsAdFrame() = 0;
virtual bool IsAdFrame() const = 0;
virtual void TraceUrlChange(const String&) = 0;
// Returns the frame type, which currently determines whether this frame is
......
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