Delay async script execution until first paint or parsing finished

This CL implements per-PendingScript async script execution delaying, as
described by the design doc [1].

Before this CL, kAsync scripts are notified of their completion in
ScriptLoader::PendingScriptFinished, which notifies ScriptRunner via
ScriptRunner::NotifyScriptReady of their completion, and queues a task
to execute them.

After this CL, when ScriptRunner::NotifyScriptReady is given a
PendingScript whose scheduling type is kAsync, it first checks to see if
the appropriate features / flags are enabled to delay async script, and
if they are the the PendingScript is eligible for delay, the script is
moved to a new |pending_delayed_async_scripts_| HeapDeque. The script is
held here until the ScriptRunner is notified that the delayed async
scripts (if any), can be executed.

The script's element document is responsible for notifying the
ScriptRunner at the correct time, that any pending delayed async scripts
can be executed.

Caveat: Currently ClassicPendingScript::IsEligibleForDelay() returns
false if the script was preloaded, since for experimentation, we're
using this as a signal that the script is higher-than-usual priority,
and should not be subject to delay.

[1]: https://docs.google.com/document/d/1G-IUrT4enARZlsIrFQ4d4cRVe9MRTJASfWwolV09JZE/edit#heading=h.yzknv6nt402r

Bug: 1086227
Change-Id: Ib944216126df663195bdc518be57504f923cee12
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2213343
Commit-Queue: Dominic Farolino <[email protected]>
Reviewed-by: Hiroshige Hayashizaki <[email protected]>
Reviewed-by: Kinuko Yasuda <[email protected]>
Reviewed-by: Kouhei Ueno <[email protected]>
Reviewed-by: Robert Kaplow <[email protected]>
Cr-Commit-Position: refs/heads/master@{#777130}
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 3f796ea..8bf2c52 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1759,6 +1759,10 @@
     "changed to indicate a tablet device. Web content optimized for tablets is "
     "received there after for the current tab.";
 
+const char kDelayAsyncScriptExecutionName[] = "Delay Async Script Execution";
+const char kDelayAsyncScriptExecutionDescription[] =
+    "The execution of async scripts will be delayed.";
+
 const char kPrefetchPrivacyChangesName[] =
     "Prefetch request properties are updated to be privacy-preserving";
 const char kPrefetchPrivacyChangesDescription[] =