Commit 48a04499 authored by Michael Crouse's avatar Michael Crouse Committed by Commit Bot

Persist the Session Statistics from the previous session.

This change persists the FCP session statistics used by the prediction
manager using a pref so that the first page load of the next session
will have a non-zero value for the first page load of the session.
This should improve the accuracy of the slow page prediction model
in these cases.

Bug: 1036026
Change-Id: I015c4ce5d654af614e947ae2352b4c75d6059067
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1977745Reviewed-by: default avatarSophie Chang <sophiechang@chromium.org>
Reviewed-by: default avatarRobert Ogden <robertogden@chromium.org>
Commit-Queue: Michael Crouse <mcrouse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#727173}
parent 00b69d8a
......@@ -214,6 +214,10 @@ void PredictionManager::Initialize(const std::vector<proto::OptimizationTarget>&
void PredictionManager::UpdateFCPSessionStatistics(base::TimeDelta fcp) {
previous_load_fcp_ms_ = static_cast<float>(fcp.InMilliseconds());
session_fcp_.AddSample(*previous_load_fcp_ms_);
pref_service_->SetDouble(prefs::kSessionStatisticFCPMean,
session_fcp_.GetMean());
pref_service_->SetDouble(prefs::kSessionStatisticFCPStdDev,
session_fcp_.GetStdDev());
}
void PredictionManager::RegisterOptimizationTargets(
......@@ -288,10 +292,18 @@ base::Optional<float> PredictionManager::GetValueForClientFeature(
navigation_handle->GetURL(), navigation_handle->GetPreviousURL()));
}
case proto::CLIENT_MODEL_FEATURE_FIRST_CONTENTFUL_PAINT_SESSION_MEAN: {
if (session_fcp_.GetNumberOfSamples() == 0) {
return static_cast<float>(
pref_service_->GetDouble(prefs::kSessionStatisticFCPMean));
}
return session_fcp_.GetMean();
}
case proto::
CLIENT_MODEL_FEATURE_FIRST_CONTENTFUL_PAINT_SESSION_STANDARD_DEVIATION: {
if (session_fcp_.GetNumberOfSamples() == 0) {
return static_cast<float>(
pref_service_->GetDouble(prefs::kSessionStatisticFCPStdDev));
}
return session_fcp_.GetStdDev();
}
case proto::
......
......@@ -495,6 +495,8 @@ class PredictionManagerTest
base::FilePath temp_dir() const { return temp_dir_.GetPath(); }
TestingPrefServiceSimple* pref_service() const { return pref_service_.get(); }
void RunUntilIdle() {
task_environment_.RunUntilIdle();
base::RunLoop().RunUntilIdle();
......@@ -1466,6 +1468,69 @@ INSTANTIATE_TEST_SUITE_P(ClientFeature,
testing::Range(proto::ClientModelFeature_MIN,
proto::ClientModelFeature_MAX));
TEST_F(PredictionManagerTest, PreviousSessionStatisticsUsed) {
base::HistogramTester histogram_tester;
GURL previous_url = GURL("https://foo.com");
std::unique_ptr<content::MockNavigationHandle> navigation_handle =
CreateMockNavigationHandleWithOptimizationGuideWebContentsObserver(
previous_url);
navigation_handle->set_url(previous_url);
navigation_handle->set_page_transition(
ui::PageTransition::PAGE_TRANSITION_RELOAD);
ON_CALL(*navigation_handle, GetPreviousURL())
.WillByDefault(testing::ReturnRef(previous_url));
pref_service()->SetDouble(optimization_guide::prefs::kSessionStatisticFCPMean,
200.0);
pref_service()->SetDouble(
optimization_guide::prefs::kSessionStatisticFCPStdDev, 50.0);
CreatePredictionManager({});
prediction_manager()->SetPredictionModelFetcherForTesting(
BuildTestPredictionModelFetcher(
PredictionModelFetcherEndState::kFetchFailed));
prediction_manager()->RegisterOptimizationTargets(
{proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD});
SetStoreInitialized();
std::unique_ptr<proto::GetModelsResponse> get_models_response =
BuildGetModelsResponse(
{},
{proto::CLIENT_MODEL_FEATURE_FIRST_CONTENTFUL_PAINT_SESSION_MEAN,
proto::
CLIENT_MODEL_FEATURE_FIRST_CONTENTFUL_PAINT_SESSION_STANDARD_DEVIATION});
prediction_manager()->UpdateHostModelFeaturesForTesting(
get_models_response.get());
prediction_manager()->UpdatePredictionModelsForTesting(
get_models_response.get());
EXPECT_EQ(OptimizationTargetDecision::kPageLoadMatches,
prediction_manager()->ShouldTargetNavigation(
navigation_handle.get(),
proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD));
TestPredictionModel* test_prediction_model =
static_cast<TestPredictionModel*>(
prediction_manager()->GetPredictionModelForTesting(
proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD));
EXPECT_TRUE(test_prediction_model);
EXPECT_TRUE(test_prediction_model->WasModelEvaluated());
base::flat_map<std::string, float> evaluated_features =
test_prediction_model->last_evaluated_features();
EXPECT_FLOAT_EQ(
evaluated_features
["CLIENT_MODEL_FEATURE_FIRST_CONTENTFUL_PAINT_SESSION_MEAN"],
200.0);
EXPECT_FLOAT_EQ(
evaluated_features["CLIENT_MODEL_FEATURE_FIRST_CONTENTFUL_PAINT_"
"SESSION_STANDARD_DEVIATION"],
50.0);
}
TEST_F(PredictionManagerTest,
StoreInitializedAfterOptimizationTargetRegistered) {
CreatePredictionManager({});
......
......@@ -55,6 +55,14 @@ const char kHintsFetcherTopHostBlacklistMinimumEngagementScore[] =
const char kHintsFetcherHostsSuccessfullyFetched[] =
"optimization_guide.hintsfetcher.hosts_successfully_fetched";
// A double pref that stores the running mean FCP.
const char kSessionStatisticFCPMean[] =
"optimization_guide.session_statistic.fcp_mean";
// A double pref that stores the running FCP standard deviation.
const char kSessionStatisticFCPStdDev[] =
"optimization_guide.session_statistic.fcp_std_dev";
// A string pref that stores the version of the Optimization Hints component
// that is currently being processed. This pref is cleared once processing
// completes. It is used for detecting a potential crash loop on processing a
......@@ -82,6 +90,10 @@ void RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterDoublePref(kTimeHintsFetcherTopHostBlacklistLastInitialized,
0, PrefRegistry::LOSSY_PREF);
registry->RegisterDoublePref(kSessionStatisticFCPMean, 0,
PrefRegistry::LOSSY_PREF);
registry->RegisterDoublePref(kSessionStatisticFCPStdDev, 0,
PrefRegistry::LOSSY_PREF);
// Use a default value of MinTopHostEngagementScoreThreshold() for the
// threshold. This ensures that the users for which this pref can't be
// computed (possibly because they had the blacklist initialized before this
......
......@@ -20,6 +20,8 @@ extern const char kTimeHintsFetcherTopHostBlacklistLastInitialized[];
extern const char kHintsFetcherTopHostBlacklistMinimumEngagementScore[];
extern const char kHintsFetcherHostsSuccessfullyFetched[];
extern const char kPendingHintsProcessingVersion[];
extern const char kSessionStatisticFCPMean[];
extern const char kSessionStatisticFCPStdDev[];
// State of |HintsFetcherTopHostsBlacklist|. The blacklist begins in
// kNotInitialized and transitions to kInitialized after
......
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