Commit 5c969016 authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

OptimizationGuide: Pass hints for DelayCompetingLowPriorityRequests to Blink

This CL passes the hints for DelayCompetingLowPriorityRequests from
BlinkOptimizationGuideWebContentsObserver in the browser process to
LocalFrame in a renderer process.

Subsequent CLs will actually plumb the hints into the resource scheduler.

Bug: 1112515
Change-Id: I567b44f13d8fcce157be5bdab7271021997b04d8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2389380
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarSophie Chang <sophiechang@chromium.org>
Reviewed-by: default avatarDominic Farolino <dom@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804668}
parent 26ad8261
......@@ -12,6 +12,7 @@
#include "chrome/test/base/ui_test_utils.h"
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/proto/delay_async_script_execution_metadata.pb.h"
#include "components/optimization_guide/proto/delay_competing_low_priority_requests_metadata.pb.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/notification_types.h"
#include "content/public/test/browser_test.h"
......@@ -110,6 +111,17 @@ class BlinkOptimizationGuideBrowserTest
blink::features::kDelayAsyncScriptExecution);
}
break;
case proto::OptimizationType::DELAY_COMPETING_LOW_PRIORITY_REQUESTS:
if (IsFeatureFlagEnabled()) {
std::map<std::string, std::string> parameters;
parameters["until"] = "use_optimization_guide";
enabled_features.emplace_back(
blink::features::kDelayCompetingLowPriorityRequests, parameters);
} else {
disabled_features.push_back(
blink::features::kDelayCompetingLowPriorityRequests);
}
break;
default:
NOTREACHED();
break;
......@@ -130,6 +142,15 @@ class BlinkOptimizationGuideBrowserTest
optimization_guide_metadata.SetAnyMetadataForTesting(metadata);
break;
}
case proto::OptimizationType::DELAY_COMPETING_LOW_PRIORITY_REQUESTS: {
proto::DelayCompetingLowPriorityRequestsMetadata metadata;
metadata.set_delay_type(
proto::PerfectHeuristicsDelayType::DELAY_TYPE_FIRST_PAINT);
metadata.set_priority_threshold(
proto::PriorityThreshold::PRIORITY_THRESHOLD_HIGH);
optimization_guide_metadata.SetAnyMetadataForTesting(metadata);
break;
}
default:
NOTREACHED();
break;
......@@ -158,6 +179,18 @@ class BlinkOptimizationGuideBrowserTest
hints.delay_async_script_execution_hints->delay_type);
}
return !!hints.delay_async_script_execution_hints;
case proto::OptimizationType::DELAY_COMPETING_LOW_PRIORITY_REQUESTS:
using blink::mojom::DelayCompetingLowPriorityRequestsDelayType;
using blink::mojom::DelayCompetingLowPriorityRequestsPriorityThreshold;
if (hints.delay_competing_low_priority_requests_hints) {
EXPECT_EQ(
DelayCompetingLowPriorityRequestsDelayType::kFirstPaint,
hints.delay_competing_low_priority_requests_hints->delay_type);
EXPECT_EQ(DelayCompetingLowPriorityRequestsPriorityThreshold::kHigh,
hints.delay_competing_low_priority_requests_hints
->priority_threshold);
}
return !!hints.delay_competing_low_priority_requests_hints;
default:
NOTREACHED();
return false;
......@@ -169,6 +202,13 @@ class BlinkOptimizationGuideBrowserTest
case proto::OptimizationType::DELAY_ASYNC_SCRIPT_EXECUTION:
return GetURLWithMockHost(
"/optimization_guide/delay-async-script-execution.html");
case proto::OptimizationType::DELAY_COMPETING_LOW_PRIORITY_REQUESTS:
// Use the URL for DelayAsyncScriptExecution to avoid test failures
// because of unimplemented UKM.
// TODO(https://crbug.com/1112515): Add UKM for
// DelayCompetingLowPriorityRequests and test it.
return GetURLWithMockHost(
"/optimization_guide/delay-async-script-execution.html");
default:
NOTREACHED();
return GURL();
......@@ -188,6 +228,10 @@ class BlinkOptimizationGuideBrowserTest
kdelay_async_script_execution_before_finished_parsingName,
1u);
break;
case proto::OptimizationType::DELAY_COMPETING_LOW_PRIORITY_REQUESTS:
// TODO(https://crbug.com/1112515): Add UKM for
// DelayCompetingLowPriorityRequests and test it.
break;
default:
NOTREACHED();
return;
......@@ -208,7 +252,9 @@ INSTANTIATE_TEST_SUITE_P(
BlinkOptimizationGuideBrowserTest,
testing::Combine(
// The optimization type.
testing::Values(proto::OptimizationType::DELAY_ASYNC_SCRIPT_EXECUTION),
testing::Values(
proto::OptimizationType::DELAY_ASYNC_SCRIPT_EXECUTION,
proto::OptimizationType::DELAY_COMPETING_LOW_PRIORITY_REQUESTS),
// Whether the feature flag for the optimization type is enabled.
testing::Bool()));
......
......@@ -18,4 +18,14 @@ bool ShouldUseOptimizationGuideForDelayAsyncScript() {
return is_feature_enabled;
}
bool ShouldUseOptimizationGuideForDelayCompetingLowPriorityRequests() {
static const bool is_feature_enabled =
base::FeatureList::IsEnabled(
blink::features::kDelayCompetingLowPriorityRequests) &&
blink::features::kDelayCompetingLowPriorityRequestsDelayParam.Get() ==
blink::features::DelayCompetingLowPriorityRequestsDelayType::
kUseOptimizationGuide;
return is_feature_enabled;
}
} // namespace optimization_guide
......@@ -9,6 +9,8 @@ namespace optimization_guide {
bool ShouldUseOptimizationGuideForDelayAsyncScript();
bool ShouldUseOptimizationGuideForDelayCompetingLowPriorityRequests();
} // namespace optimization_guide
#endif // CHROME_BROWSER_OPTIMIZATION_GUIDE_BLINK_BLINK_OPTIMIZATION_GUIDE_FEATURE_FLAG_HELPER_H_
......@@ -8,6 +8,7 @@
#include "chrome/browser/optimization_guide/blink/blink_optimization_guide_feature_flag_helper.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
#include "components/optimization_guide/proto/delay_async_script_execution_metadata.pb.h"
#include "components/optimization_guide/proto/delay_competing_low_priority_requests_metadata.pb.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
......@@ -41,6 +42,10 @@ void BlinkOptimizationGuideInquirer::InquireHints(
supported_optimization_types.push_back(
proto::OptimizationType::DELAY_ASYNC_SCRIPT_EXECUTION);
}
if (ShouldUseOptimizationGuideForDelayCompetingLowPriorityRequests()) {
supported_optimization_types.push_back(
proto::OptimizationType::DELAY_COMPETING_LOW_PRIORITY_REQUESTS);
}
for (auto optimization_type : supported_optimization_types) {
// CanApplyOptimizationAsync() synchronously runs the callback when the
......@@ -71,6 +76,9 @@ void BlinkOptimizationGuideInquirer::DidInquireHints(
case proto::OptimizationType::DELAY_ASYNC_SCRIPT_EXECUTION:
PopulateHintsForDelayAsyncScriptExecution(metadata);
break;
case proto::OptimizationType::DELAY_COMPETING_LOW_PRIORITY_REQUESTS:
PopulateHintsForDelayCompetingLowPriorityRequests(metadata);
break;
default:
NOTREACHED();
break;
......@@ -114,4 +122,56 @@ void BlinkOptimizationGuideInquirer::PopulateHintsForDelayAsyncScriptExecution(
std::move(hints);
}
void BlinkOptimizationGuideInquirer::
PopulateHintsForDelayCompetingLowPriorityRequests(
const OptimizationMetadata& optimization_metadata) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// Give up providing the hints when the metadata is not available.
base::Optional<proto::DelayCompetingLowPriorityRequestsMetadata> metadata =
optimization_metadata
.ParsedMetadata<proto::DelayCompetingLowPriorityRequestsMetadata>();
if (!metadata || !metadata->delay_type() || !metadata->priority_threshold())
return;
// Populate the metadata into the hints.
using ProtoDelayType = proto::PerfectHeuristicsDelayType;
using MojomDelayType =
blink::mojom::DelayCompetingLowPriorityRequestsDelayType;
auto hints = blink::mojom::DelayCompetingLowPriorityRequestsHints::New();
switch (metadata->delay_type()) {
case ProtoDelayType::DELAY_TYPE_UNKNOWN:
hints->delay_type = MojomDelayType::kUnknown;
break;
case ProtoDelayType::DELAY_TYPE_FIRST_PAINT:
hints->delay_type = MojomDelayType::kFirstPaint;
break;
case ProtoDelayType::DELAY_TYPE_FIRST_CONTENTFUL_PAINT:
hints->delay_type = MojomDelayType::kFirstContentfulPaint;
break;
case ProtoDelayType::DELAY_TYPE_FINISHED_PARSING:
case ProtoDelayType::DELAY_TYPE_FIRST_PAINT_OR_FINISHED_PARSING:
// DelayCompetingLowPriorityRequests doesn't support these milestones.
NOTREACHED();
return;
}
using MojomPriorityThreshold =
blink::mojom::DelayCompetingLowPriorityRequestsPriorityThreshold;
switch (metadata->priority_threshold()) {
case proto::PriorityThreshold::PRIORITY_THRESHOLD_UNKNOWN:
hints->priority_threshold = MojomPriorityThreshold::kUnknown;
break;
case proto::PriorityThreshold::PRIORITY_THRESHOLD_MEDIUM:
hints->priority_threshold = MojomPriorityThreshold::kMedium;
break;
case proto::PriorityThreshold::PRIORITY_THRESHOLD_HIGH:
hints->priority_threshold = MojomPriorityThreshold::kHigh;
break;
}
DCHECK(
!optimization_guide_hints_->delay_competing_low_priority_requests_hints);
optimization_guide_hints_->delay_competing_low_priority_requests_hints =
std::move(hints);
}
} // namespace optimization_guide
......@@ -58,6 +58,8 @@ class BlinkOptimizationGuideInquirer {
void PopulateHintsForDelayAsyncScriptExecution(
const OptimizationMetadata& optimization_metadata);
void PopulateHintsForDelayCompetingLowPriorityRequests(
const OptimizationMetadata& optimization_metadata);
// The hints currently available.
blink::mojom::BlinkOptimizationGuideHintsPtr optimization_guide_hints_;
......
......@@ -90,6 +90,10 @@ BlinkOptimizationGuideWebContentsObserver::
std::vector<proto::OptimizationType> opts;
if (ShouldUseOptimizationGuideForDelayAsyncScript())
opts.push_back(proto::OptimizationType::DELAY_ASYNC_SCRIPT_EXECUTION);
if (ShouldUseOptimizationGuideForDelayCompetingLowPriorityRequests()) {
opts.push_back(
proto::OptimizationType::DELAY_COMPETING_LOW_PRIORITY_REQUESTS);
}
if (!opts.empty())
decider->RegisterOptimizationTypes(opts);
}
......
......@@ -90,11 +90,23 @@ void ResourceLoadingHintsAgent::DidCreateNewDocument() {
// TODO(https://crbug.com/1113980): Onion-soupify the optimization guide for
// Blink so that we can directly pass the hints without mojom variant
// conversion.
if (blink_optimization_guide_hints_ &&
blink_optimization_guide_hints_->delay_async_script_execution_hints) {
web_frame->SetOptimizationGuideHints(
blink_optimization_guide_hints_->delay_async_script_execution_hints
->delay_type);
if (blink_optimization_guide_hints_) {
blink::WebOptimizationGuideHints hints;
if (blink_optimization_guide_hints_->delay_async_script_execution_hints) {
hints.delay_async_script_execution_delay_type =
blink_optimization_guide_hints_->delay_async_script_execution_hints
->delay_type;
}
if (blink_optimization_guide_hints_
->delay_competing_low_priority_requests_hints) {
hints.delay_competing_low_priority_requests_delay_type =
blink_optimization_guide_hints_
->delay_competing_low_priority_requests_hints->delay_type;
hints.delay_competing_low_priority_requests_priority_threshold =
blink_optimization_guide_hints_
->delay_competing_low_priority_requests_hints->priority_threshold;
}
web_frame->SetOptimizationGuideHints(hints);
}
// Once the hints are sent to the local frame, clear the local copy to prevent
// accidental reuse.
......
......@@ -594,7 +594,9 @@ const base::FeatureParam<DelayCompetingLowPriorityRequestsDelayType>::Option
"first_paint"},
{DelayCompetingLowPriorityRequestsDelayType::kFirstContentfulPaint,
"first_contentful_paint"},
{DelayCompetingLowPriorityRequestsDelayType::kAlways, "always"}};
{DelayCompetingLowPriorityRequestsDelayType::kAlways, "always"},
{DelayCompetingLowPriorityRequestsDelayType::kUseOptimizationGuide,
"use_optimization_guide"}};
const base::FeatureParam<DelayCompetingLowPriorityRequestsDelayType>
kDelayCompetingLowPriorityRequestsDelayParam{
&kDelayCompetingLowPriorityRequests, "until",
......
......@@ -356,6 +356,7 @@ source_set("blink_headers") {
"web/web_navigation_policy.h",
"web/web_navigation_type.h",
"web/web_node.h",
"web/web_optimization_guide_hints.h",
"web/web_option_element.h",
"web/web_origin_policy.h",
"web/web_page_popup.h",
......
......@@ -197,6 +197,7 @@ enum class DelayCompetingLowPriorityRequestsDelayType {
kFirstPaint,
kFirstContentfulPaint,
kAlways,
kUseOptimizationGuide,
};
BLINK_COMMON_EXPORT extern const base::FeatureParam<
DelayCompetingLowPriorityRequestsDelayType>
......
......@@ -22,11 +22,41 @@ struct DelayAsyncScriptExecutionHints {
DelayAsyncScriptExecutionDelayType delay_type;
};
// Enumerates the milestones at which competing low priority requests can be
// delayed until.
enum DelayCompetingLowPriorityRequestsDelayType {
// No delay (default behavior).
kUnknown,
// Delay until first paint.
kFirstPaint,
// Delay until first contentful paint.
kFirstContentfulPaint,
};
// Enumerates the different request priorities that the resource scheduler will
// consider "important". For example, low priority requests will be queued
// behind in-flight medium priority requests, when the threshold is kMedium,
// etc.
enum DelayCompetingLowPriorityRequestsPriorityThreshold {
kUnknown,
kMedium,
kHigh,
};
// Hints for delay competing low priority requests optimization.
struct DelayCompetingLowPriorityRequestsHints {
DelayCompetingLowPriorityRequestsDelayType delay_type;
DelayCompetingLowPriorityRequestsPriorityThreshold priority_threshold;
};
// The set of optimization hints for Blink provided by the optimization guide
// service in the browser process.
//
// Each hint is optional as only a part of them might be populated. For now
// |delay_async_script_execution_hints| is the only hints.
// Each hint is optional as only a part of them might be populated.
struct BlinkOptimizationGuideHints {
DelayAsyncScriptExecutionHints? delay_async_script_execution_hints;
DelayCompetingLowPriorityRequestsHints?
delay_competing_low_priority_requests_hints;
};
......@@ -30,7 +30,6 @@
#include "third_party/blink/public/mojom/frame/lifecycle.mojom-shared.h"
#include "third_party/blink/public/mojom/frame/media_player_action.mojom-shared.h"
#include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom-shared.h"
#include "third_party/blink/public/mojom/optimization_guide/optimization_guide.mojom-shared.h"
#include "third_party/blink/public/mojom/portal/portal.mojom-shared.h"
#include "third_party/blink/public/mojom/selection_menu/selection_menu_behavior.mojom-shared.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h"
......@@ -43,6 +42,7 @@
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/public/web/web_navigation_params.h"
#include "third_party/blink/public/web/web_optimization_guide_hints.h"
#include "ui/accessibility/ax_tree_id.h"
#include "ui/base/ime/ime_text_span.h"
#include "v8/include/v8.h"
......@@ -742,11 +742,7 @@ class WebLocalFrame : public WebFrame {
// Sets the optimization hints provided by the optimization guide service. See
// //components/optimization_guide/README.md.
//
// For now, DelayAsyncScriptExecutionDelayType is the only hint. If more hints
// are added, this can be struct, etc.
virtual void SetOptimizationGuideHints(
mojom::DelayAsyncScriptExecutionDelayType delay_type) = 0;
virtual void SetOptimizationGuideHints(const WebOptimizationGuideHints&) = 0;
// Testing ------------------------------------------------------------------
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_OPTIMIZATION_GUIDE_HINTS_H_
#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_OPTIMIZATION_GUIDE_HINTS_H_
#include "base/optional.h"
#include "third_party/blink/public/mojom/optimization_guide/optimization_guide.mojom-shared.h"
namespace blink {
struct WebOptimizationGuideHints {
base::Optional<mojom::DelayAsyncScriptExecutionDelayType>
delay_async_script_execution_delay_type;
base::Optional<mojom::DelayCompetingLowPriorityRequestsDelayType>
delay_competing_low_priority_requests_delay_type;
base::Optional<mojom::DelayCompetingLowPriorityRequestsPriorityThreshold>
delay_competing_low_priority_requests_priority_threshold;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_OPTIMIZATION_GUIDE_HINTS_H_
......@@ -629,7 +629,7 @@ bool WebLocalFrameImpl::ConsumeTransientUserActivation(
}
void WebLocalFrameImpl::SetOptimizationGuideHints(
mojom::blink::DelayAsyncScriptExecutionDelayType delay_type) {
const WebOptimizationGuideHints& web_hints) {
if (!GetFrame())
return;
// Re-build the optimization hints.
......@@ -637,8 +637,19 @@ void WebLocalFrameImpl::SetOptimizationGuideHints(
// Blink so that we can directly pass the hints without mojom variant
// conversion.
auto hints = mojom::blink::BlinkOptimizationGuideHints::New();
hints->delay_async_script_execution_hints =
mojom::blink::DelayAsyncScriptExecutionHints::New(delay_type);
if (web_hints.delay_async_script_execution_delay_type) {
hints->delay_async_script_execution_hints =
mojom::blink::DelayAsyncScriptExecutionHints::New(
*web_hints.delay_async_script_execution_delay_type);
}
if (web_hints.delay_competing_low_priority_requests_delay_type &&
web_hints.delay_competing_low_priority_requests_priority_threshold) {
hints->delay_competing_low_priority_requests_hints =
mojom::blink::DelayCompetingLowPriorityRequestsHints::New(
*web_hints.delay_competing_low_priority_requests_delay_type,
*web_hints
.delay_competing_low_priority_requests_priority_threshold);
}
GetFrame()->SetOptimizationGuideHints(std::move(hints));
}
......
......@@ -306,8 +306,7 @@ class CORE_EXPORT WebLocalFrameImpl final
bool HasStickyUserActivation() override;
bool HasTransientUserActivation() override;
bool ConsumeTransientUserActivation(UserActivationUpdateSource) override;
void SetOptimizationGuideHints(
mojom::blink::DelayAsyncScriptExecutionDelayType delay_type) override;
void SetOptimizationGuideHints(const WebOptimizationGuideHints&) override;
// WebNavigationControl overrides:
bool DispatchBeforeUnloadEvent(bool) override;
......
......@@ -828,6 +828,12 @@ class ResourceLoadSchedulerTestDelayCompetingLowPriorityRequests
case features::DelayCompetingLowPriorityRequestsDelayType::kAlways:
NOTREACHED();
break;
case features::DelayCompetingLowPriorityRequestsDelayType::
kUseOptimizationGuide:
// TODO(https://crbug.com/1112515): Plumb the optimization hints into
// the scheduler and add tests.
NOTREACHED();
break;
}
switch (priority_threshold_) {
......
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