Speculatively launch Service Workers on mouse/touch events. [5/5]
1/5: Introduce NavigationHintSender.
https://codereview.chromium.org/2043863003/
2/5: Pipe NavigationHints from NavigationHintSender to ChromeRenderMessageFilter
https://codereview.chromium.org/2043083002/
3/5: Call StartServiceWorkerForNavigationHint() from ChromeRenderMessageFilter
https://codereview.chromium.org/2052613003/
4/5: Measure the precision of the speculative launch of Service Workers for
NavigationHints
https://codereview.chromium.org/2045153003/
5/5: Add flags to enable SupeculativeLaunchServiceWorker
This CL.
This CL introduces a new feature named "SpeculativeLaunchServiceWorker".
When the feature is enabled, Service Workers are speculatively started on the
user's mousedown/touch events.
Demo:
https://drive.google.com/file/d/0B6skYAFVnosEMWdzRm4yMEtIMkk/view?usp=sharing
BUG=616502
Review-Url: https://codereview.chromium.org/2053573002
Cr-Commit-Position: refs/heads/master@{#410295}
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 7129b381..61bbab3 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6311,6 +6311,12 @@
<message name="IDS_FLAGS_V8_CACHE_STRATEGIES_FOR_CACHE_STORAGE_AGGRESSIVE" desc="The V8 cache for CacheStorage supports three strategies: disabled; caching same as if the script is in HTTPCache; force caching on the first load. This option describes the 3rd of these, force caching on the first load.">
Aggressive
</message>
+ <message name="IDS_FLAGS_SPECULATIVE_LAUNCH_SERVICE_WORKER_NAME" desc="Name of the about::flags setting for speculative launch of service workers.">
+ Speculative launch of service workers.
+ </message>
+ <message name="IDS_FLAGS_SPECULATIVE_LAUNCH_SERVICE_WORKER_DESCRIPTION" desc="Description of the about::flags setting for speculative launch of service workers.">
+ Speculatively launch service workers using touch and mouse events.
+ </message>
<!-- Data Reduction Proxy -->
<message name="IDS_FLAGS_DATA_REDUCTION_PROXY_LO_FI_NAME" desc="An about::flags experiment title to enable/disable Data Saver Lo-Fi" translateable="false">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 74b692c..08e1cde0 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1119,6 +1119,10 @@
IDS_FLAGS_SUGGESTIONS_WITH_SUB_STRING_MATCH_DESCRIPTION, kOsAll,
SINGLE_VALUE_TYPE(
autofill::switches::kEnableSuggestionsWithSubstringMatch)},
+ {"enable-speculative-launch-service-worker",
+ IDS_FLAGS_SPECULATIVE_LAUNCH_SERVICE_WORKER_NAME,
+ IDS_FLAGS_SPECULATIVE_LAUNCH_SERVICE_WORKER_DESCRIPTION, kOsAll,
+ FEATURE_VALUE_TYPE(features::kSpeculativeLaunchServiceWorker)},
{"enable-supervised-user-managed-bookmarks-folder",
IDS_FLAGS_SUPERVISED_USER_MANAGED_BOOKMARKS_FOLDER_NAME,
IDS_FLAGS_SUPERVISED_USER_MANAGED_BOOKMARKS_FOLDER_DESCRIPTION, kOsAll,
diff --git a/chrome/browser/chrome_service_worker_browsertest.cc b/chrome/browser/chrome_service_worker_browsertest.cc
index ac5f1c4d..834b3d97 100644
--- a/chrome/browser/chrome_service_worker_browsertest.cc
+++ b/chrome/browser/chrome_service_worker_browsertest.cc
@@ -12,6 +12,7 @@
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/histogram_tester.h"
#include "build/build_config.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile.h"
@@ -26,6 +27,8 @@
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "ppapi/shared_impl/ppapi_switches.h"
@@ -516,4 +519,86 @@
ExecutePNACLUrlLoaderTest("OtherCORSCredentials"));
}
+class ServiceWorkerSpeculativeLaunchTest : public ChromeServiceWorkerTest {
+ protected:
+ ServiceWorkerSpeculativeLaunchTest() {}
+ ~ServiceWorkerSpeculativeLaunchTest() override {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitchASCII(
+ switches::kEnableFeatures,
+ features::kSpeculativeLaunchServiceWorker.name);
+ }
+
+ base::HistogramTester histogram_tester_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSpeculativeLaunchTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ServiceWorkerSpeculativeLaunchTest, MouseDown) {
+ WriteFile(
+ FILE_PATH_LITERAL("sw.js"),
+ "self.onfetch = function(e) {"
+ " e.respondWith(new Response('<title>Done</title>',"
+ " {headers: {'Content-Type': 'text/html'}}));"
+ "};");
+ WriteFile(
+ FILE_PATH_LITERAL("test.html"),
+ "<script>"
+ "navigator.serviceWorker.register('./sw.js', {scope: './scope/'})"
+ " .then(function(reg) {"
+ " reg.addEventListener('updatefound', function() {"
+ " var worker = reg.installing;"
+ " worker.addEventListener('statechange', function() {"
+ " if (worker.state == 'activated')"
+ " document.title = 'READY';"
+ " });"
+ " });"
+ " });"
+ "</script>"
+ "<body style='margin:0; padding:0;'>"
+ "<a href='./scope/' style='position:fixed; width:1px; height:1px;'></a>"
+ "</body>");
+
+ embedded_test_server()->ServeFilesFromDirectory(service_worker_dir_.path());
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ content::ServiceWorkerContext* sw_context =
+ content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
+ ->GetServiceWorkerContext();
+
+ const base::string16 expected_title1 = base::ASCIIToUTF16("READY");
+ content::TitleWatcher title_watcher1(
+ browser()->tab_strip_model()->GetActiveWebContents(), expected_title1);
+ ui_test_utils::NavigateToURL(browser(),
+ embedded_test_server()->GetURL("/test.html"));
+ EXPECT_EQ(expected_title1, title_watcher1.WaitAndGetTitle());
+
+ histogram_tester_.ExpectBucketCount("ServiceWorker.StartNewWorker.Status",
+ 0 /* SERVICE_WORKER_OK */, 1);
+
+ sw_context->StopAllServiceWorkersForOrigin(
+ embedded_test_server()->base_url());
+
+ const base::string16 expected_title2 = base::ASCIIToUTF16("Done");
+ content::TitleWatcher title_watcher2(
+ browser()->tab_strip_model()->GetActiveWebContents(), expected_title2);
+
+ histogram_tester_.ExpectTotalCount(
+ "ServiceWorker.StartWorker.StatusByPurpose_NAVIGATION_HINT_LINK_MOUSE_"
+ "DOWN",
+ 0);
+ content::SimulateMouseClickAt(
+ browser()->tab_strip_model()->GetActiveWebContents(), 0,
+ blink::WebMouseEvent::ButtonLeft, gfx::Point(0, 0));
+ EXPECT_EQ(expected_title2, title_watcher2.WaitAndGetTitle());
+
+ // The service worker must be started by a navigation hint.
+ histogram_tester_.ExpectBucketCount(
+ "ServiceWorker.StartWorker.StatusByPurpose_NAVIGATION_HINT_LINK_MOUSE_"
+ "DOWN",
+ 0 /* SERVICE_WORKER_OK */, 1);
+}
+
} // namespace
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 6c23bd38..873f2c9d 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -261,6 +261,9 @@
base::FeatureList::IsEnabled(features::kWebPayments));
#endif
+ if (base::FeatureList::IsEnabled(features::kSpeculativeLaunchServiceWorker))
+ WebRuntimeFeatures::enableSpeculativeLaunchServiceWorker(true);
+
// Enable explicitly enabled features, and then disable explicitly disabled
// ones.
if (command_line.HasSwitch(switches::kEnableBlinkFeatures)) {
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 300b692..d2a1f78 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -112,6 +112,10 @@
const base::Feature kScrollAnchoring{"ScrollAnchoring",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Speculatively launches Service Workers on mouse/touch events.
+const base::Feature kSpeculativeLaunchServiceWorker{
+ "SpeculativeLaunchServiceWorker", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Enables implementation of the Cache-Control: stale-while-revalidate directive
// which permits servers to allow the use of stale resources while revalidation
// proceeds in the background. See http://crbug.com/348877
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 7a1d388..6f87268 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -37,6 +37,7 @@
CONTENT_EXPORT extern const base::Feature kPointerEvents;
CONTENT_EXPORT extern const base::Feature kRenderingPipelineThrottling;
CONTENT_EXPORT extern const base::Feature kScrollAnchoring;
+CONTENT_EXPORT extern const base::Feature kSpeculativeLaunchServiceWorker;
CONTENT_EXPORT extern const base::Feature kStaleWhileRevalidate;
CONTENT_EXPORT extern const base::Feature kTokenBinding;
CONTENT_EXPORT extern const base::Feature kWeakMemoryCache;
diff --git a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
index f3d3de83..6e6be67 100644
--- a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
@@ -238,9 +238,8 @@
return;
}
- // TODO(horo): Call NavigationHintSender::handleEvent() when
- // SpeculativeLaunchServiceWorker feature is enabled.
- // ensureNavigationHintSender()->handleEvent(event);
+ if (RuntimeEnabledFeatures::speculativeLaunchServiceWorkerEnabled())
+ ensureNavigationHintSender()->handleEvent(event);
if (isLinkClick(event) && isLiveLink()) {
handleClick(event);
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index 583ded6..a40997d 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -206,6 +206,7 @@
// be shipped would be enabled. Instead, remove the flag from the shipping
// interface.
ExperimentalStream status=experimental
+SpeculativeLaunchServiceWorker
StorageEstimate status=experimental
Suborigins status=test
// Many websites disable mouse support when touch APIs are available. We'd
diff --git a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
index 881e5b4c..6b3569d4 100644
--- a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
@@ -230,6 +230,11 @@
RuntimeEnabledFeatures::setSlimmingPaintV2Enabled(enable);
}
+void WebRuntimeFeatures::enableSpeculativeLaunchServiceWorker(bool enable)
+{
+ RuntimeEnabledFeatures::setSpeculativeLaunchServiceWorkerEnabled(enable);
+}
+
void WebRuntimeFeatures::enableTouch(bool enable)
{
RuntimeEnabledFeatures::setTouchEnabled(enable);
diff --git a/third_party/WebKit/public/web/WebRuntimeFeatures.h b/third_party/WebKit/public/web/WebRuntimeFeatures.h
index 75fc545..2abe67c 100644
--- a/third_party/WebKit/public/web/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/web/WebRuntimeFeatures.h
@@ -103,6 +103,7 @@
BLINK_EXPORT static void enableScrollAnchoring(bool);
BLINK_EXPORT static void enableSharedWorker(bool);
BLINK_EXPORT static void enableSlimmingPaintV2(bool);
+ BLINK_EXPORT static void enableSpeculativeLaunchServiceWorker(bool);
BLINK_EXPORT static void enableTouch(bool);
BLINK_EXPORT static void enableUnsafeES3APIs(bool);
BLINK_EXPORT static void enableV8IdleTasks(bool);
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 7dd4a384..29bd28575 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -82818,6 +82818,7 @@
<int value="-667517406" label="overscroll-history-navigation"/>
<int value="-661978438" label="enable-data-reduction-proxy-lo-fi"/>
<int value="-660160292" label="enable-apps-show-on-first-paint"/>
+ <int value="-650504533" label="enable-speculative-launch-service-worker"/>
<int value="-649956990" label="enable-harfbuzz-rendertext"/>
<int value="-641719457" label="disable-compositor-touch-hit-testing"/>
<int value="-631740127" label="inert-visual-viewport"/>