Bug 1541238 - add pref to delay 3rd-party tracker; r=mayhemer
authorLiang-Heng Chen <xeonchen@gmail.com>
Fri, 05 Apr 2019 16:30:08 +0000
changeset 468269 557f1dbc18ca494c059404dae75f8729763616a4
parent 468263 a765634b9ec26b122c094ad5def8e70ea5c23e17
child 468270 ae30a382f499166b8f4037b0221799571aaefdaf
push id35826
push usernerli@mozilla.com
push dateSat, 06 Apr 2019 21:48:00 +0000
treeherdermozilla-central@dc53fe5c9ced [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1541238
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1541238 - add pref to delay 3rd-party tracker; r=mayhemer Differential Revision: https://phabricator.services.mozilla.com/D26266
modules/libpref/init/StaticPrefList.h
netwerk/protocol/http/nsHttpChannel.cpp
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -2039,16 +2039,22 @@ VARCACHE_PREF(
 
 // Telemetry of traffic categories
 VARCACHE_PREF(
   "network.traffic_analyzer.enabled",
   network_traffic_analyzer_enabled,
   RelaxedAtomicBool, false
 )
 
+VARCACHE_PREF(
+  "network.delay.tracking.load",
+   network_delay_tracking_load,
+   uint32_t, 0
+)
+
 //---------------------------------------------------------------------------
 // ContentSessionStore prefs
 //---------------------------------------------------------------------------
 // Maximum number of bytes of DOMSessionStorage data we collect per origin.
 VARCACHE_PREF(
   "browser.sessionstore.dom_storage_limit",
   browser_sessionstore_dom_storage_limit,
   uint32_t, 2048
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -6706,24 +6706,45 @@ nsresult nsHttpChannel::BeginConnect() {
 
   // We are about to do an async lookup to check if the URI is a
   // tracker. If yes, this channel will be canceled by channel classifier.
   // Chances are the lookup is not needed so CheckIsTrackerWithLocalTable()
   // will return an error and then we can BeginConnectActual() right away.
   RefPtr<nsHttpChannel> self = this;
   bool willCallback = NS_SUCCEEDED(
       AsyncUrlChannelClassifier::CheckChannel(this, [self]() -> void {
-        nsresult rv = self->BeginConnectActual();
-        if (NS_FAILED(rv)) {
-          // Since this error is thrown asynchronously so that the caller
-          // of BeginConnect() will not do clean up for us. We have to do
-          // it on our own.
-          self->CloseCacheEntry(false);
-          Unused << self->AsyncAbort(rv);
+        auto nextFunc = [self]() -> void {
+          nsresult rv = self->BeginConnectActual();
+          if (NS_FAILED(rv)) {
+            // Since this error is thrown asynchronously so that the caller
+            // of BeginConnect() will not do clean up for us. We have to do
+            // it on our own.
+            self->CloseCacheEntry(false);
+            Unused << self->AsyncAbort(rv);
+          }
+        };
+
+        uint32_t delayMillisec = StaticPrefs::network_delay_tracking_load();
+        if (self->IsThirdPartyTrackingResource() && delayMillisec) {
+          nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction(
+              "nsHttpChannel::BeginConnect-delayed", nextFunc);
+          nsresult rv = NS_DelayedDispatchToCurrentThread(runnable.forget(),
+                                                          delayMillisec);
+          if (NS_SUCCEEDED(rv)) {
+            LOG(
+                ("nsHttpChannel::BeginConnect delaying 3rd-party tracking "
+                 "resource for %u ms [this=%p]",
+                 delayMillisec, self.get()));
+            return;
+          }
+          LOG(("nsHttpChannel::BeginConnect unable to delay loading. [this=%p]",
+               self.get()));
         }
+
+        nextFunc();
       }));
 
   if (!willCallback) {
     // We can do BeginConnectActual immediately if CheckIsTrackerWithLocalTable
     // is failed. Note that we don't need to handle the failure because
     // BeginConnect() will return synchronously and the caller will be
     // responsible for handling it.
     return BeginConnectActual();