blink: Support blocking rendering until Document parsing.
Add a `blocking` attribute to the HTML element so authors can choose to
block rendering until the complete Document has been parsed.
Design:
https://docs.google.com/document/d/1MrWyy1VVa3WxTtG-uJhcPNohrWFApHmY4PRbgKKd2hg/edit?pli=1
Bug: 1470393
Change-Id: I30eb8e71cf36dcfd4355d0a1bd76f32d5a8ff061
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4753436
Auto-Submit: Khushal Sagar <khushalsagar@chromium.org>
Reviewed-by: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1182742}
diff --git a/html/dom/render-blocking/document-render-blocking-partial.tentative.html b/html/dom/render-blocking/document-render-blocking-partial.tentative.html
new file mode 100644
index 0000000..89ab05e
--- /dev/null
+++ b/html/dom/render-blocking/document-render-blocking-partial.tentative.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+ <html blocking=render>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/utils.js"></script>
+ <title>`blocking=render` defers frames until the attribute is set</title>
+ <script>
+ assert_implements(document.documentElement.blocking, "no blocking attribute");
+
+ promise_test(() => {
+ return new Promise((resolve, reject) => {
+ requestAnimationFrame(() => {
+ if (document.getElementById("last"))
+ reject();
+ else
+ resolve();
+ });
+ });
+ }, "blocking defers frames until removed");
+ </script>
+ </head>
+ <body>
+ <div id="first"></div>
+ <script>
+ jankMany(100, 10);
+ document.documentElement.blocking="";
+ </script>
+ <div id="second"></div>
+ <script>
+ jankMany(100, 10);
+ </script>
+ <div id="last"></div>
+ </body>
+</html>
diff --git a/html/dom/render-blocking/document-render-blocking.tentative.html b/html/dom/render-blocking/document-render-blocking.tentative.html
new file mode 100644
index 0000000..909029b
--- /dev/null
+++ b/html/dom/render-blocking/document-render-blocking.tentative.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+ <html blocking=render>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/utils.js"></script>
+ <title>`blocking=render` defers frames until complete document parsed</title>
+ <script>
+ assert_implements(document.documentElement.blocking, "no blocking attribute");
+
+ promise_test(() => {
+ return new Promise((resolve, reject) => {
+ requestAnimationFrame(() => {
+ if (document.getElementById("last"))
+ resolve();
+ else
+ reject();
+ });
+ });
+ }, "blocking defers frames until full parsing");
+ </script>
+ </head>
+ <body>
+ <div id="first"></div>
+ <script>
+ jankMany(100, 10);
+ </script>
+ <div id="second"></div>
+ <script>
+ jankMany(100, 10);
+ </script>
+ <div id="last"></div>
+ </body>
+</html>
diff --git a/html/dom/render-blocking/support/utils.js b/html/dom/render-blocking/support/utils.js
new file mode 100644
index 0000000..9a890ab
--- /dev/null
+++ b/html/dom/render-blocking/support/utils.js
@@ -0,0 +1,10 @@
+function jank(ms) {
+ let start = performance.now();
+ while (performance.now() < start + ms);
+}
+
+function jankMany(ms, times) {
+ for (let i = 0; i < times; i++) {
+ jank(ms);
+ }
+}