render-blocking-status-link.html (10685B)
1 <!DOCTYPE html> 2 <head> 3 <meta charset="utf-8" /> 4 <title>This test validates the render blocking status of resources.</title> 5 <link rel="help" href="https://www.w3.org/TR/resource-timing-2/#sec-performanceresourcetiming"/> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 9 <!-- Start of test cases --> 10 <script> 11 // Dynamic style using document.write in head 12 document.write(` 13 <link rel=stylesheet 14 href='resources/empty_style.css?stylesheet-head-dynamic-docWrite'> 15 `); 16 document.write(` 17 <link rel=stylesheet 18 href='resources/empty_style.css?stylesheet-head-dynamic-docWrite-print' 19 media=print> 20 `); 21 </script> 22 23 <link rel=stylesheet href="resources/empty_style.css?stylesheet-head"> 24 <link rel=stylesheet href="resources/empty_style.css?stylesheet-head-media-print" 25 media=print> 26 <link rel="alternate stylesheet" 27 href="resources/empty_style.css?stylesheet-head-alternate"> 28 <link rel=preload as=style href="resources/empty_style.css?link-style-head-preload"> 29 <link rel=preload as=style href="resources/empty_style.css?link-style-preload-used"> 30 <link rel=preload as=style href="resources/empty_style.css?link-style-preload-used-immediately"> 31 <link rel=stylesheet href="resources/empty_style.css?link-style-preload-used-immediately"> 32 <link rel=preload as=style href="resources/empty_style.css?link-style-preload-used-immediately-then-preloaded-again"> 33 <link rel=stylesheet href="resources/empty_style.css?link-style-preload-used-immediately-then-preloaded-again"> 34 <link rel=preload as=style href="resources/empty_style.css?link-style-preload-used-immediately-then-preloaded-again"> 35 <link rel=stylesheet href="resources/importer.css?stylesheet-importer-head"> 36 <link rel=stylesheet id="link-head-remove-attr" blocking="render" 37 href="resources/empty_style.css?stylesheet-head-blocking-render-remove-attr"> 38 <link rel=modulepreload href="resources/empty_script.js?link-head-modulepreload"> 39 <link rel=preload as="script" href="resources/empty_script.js?link-script-preload-used-immediately"> 40 <script src="resources/empty_script.js?link-script-preload-used-immediately"></script> 41 <link rel=preload as="script" href="resources/empty_script.js?link-script-preload-defer-used-immediately"> 42 <script defer src="resources/empty_script.js?link-script-preload-defer-used-immediately"></script> 43 44 <style>@import url(resources/empty_style.css?stylesheet-inline-imported);</style> 45 <style media=print> 46 @import url(resources/empty_style.css?stylesheet-inline-imported-print); 47 </style> 48 </head> 49 50 <body> 51 52 <link rel=stylesheet href="resources/empty_style.css?stylesheet-body"> 53 <link rel=stylesheet href="resources/importer.css?stylesheet-importer-body"> 54 <link rel=stylesheet href="resources/empty_style.css?stylesheet-body-media-print" 55 media=print> 56 <link rel=stylesheet blocking="render" 57 href="resources/empty_style.css?stylesheet-body-blocking-render"> 58 59 <img src="resources/blue.png?link-image-preload-used-immediately"> 60 61 <!-- https://html.spec.whatwg.org/multipage/urls-and-fetching.html#blocking-attributes 62 mentions that an element is potentially render-blocking if its blocking 63 tokens set contains "render", or if it is implicitly potentially 64 render-blocking. By default, an element is not implicitly potentially 65 render-blocking. 66 https://html.spec.whatwg.org/multipage/links.html#link-type-stylesheet 67 specifies that a link element of type stylesheet is implicitly potentially 68 render-blocking only if the element was created by its node document's parser. --> 69 <script> 70 // Dynamic style using document.write in body 71 document.write(` 72 <link rel=stylesheet 73 href='resources/empty_style.css?stylesheet-body-dynamic-docWrite'> 74 `); 75 document.write(` 76 <link rel=stylesheet 77 href='resources/empty_style.css?stylesheet-body-dynamic-docWrite-print' 78 media=print> 79 `); 80 81 // Dynamic style using innerHTML 82 document.head.innerHTML += ` 83 <link rel=stylesheet 84 href='resources/empty_style.css?stylesheet-head-dynamic-innerHTML'> 85 `; 86 document.head.innerHTML += ` 87 <link rel=stylesheet 88 href='resources/empty_style.css?stylesheet-head-dynamic-innerHTML-print' 89 media=print> 90 `; 91 document.head.innerHTML += ` 92 <link rel=stylesheet blocking=render 93 href='resources/empty_style.css?stylesheet-head-blocking-render-dynamic-innerHTML'> 94 `; 95 96 // Dynamic style using DOM API 97 var link = document.createElement("link"); 98 link.href = "resources/empty_style.css?stylesheet-head-dynamic-dom"; 99 link.rel = "stylesheet"; 100 document.head.appendChild(link); 101 102 // Add a dynamic render-blocking style with DOM API 103 link = document.createElement("link"); 104 link.href = "resources/empty_style.css?stylesheet-head-blocking-render-dynamic-dom"; 105 link.rel = "stylesheet"; 106 link.blocking = "render"; 107 document.head.appendChild(link); 108 109 // Dynamic style preload using DOM API 110 link = document.createElement("link"); 111 link.href = "resources/empty_style.css?link-style-head-preload-dynamic-dom"; 112 link.rel = "preload"; 113 link.as = "style"; 114 document.head.appendChild(link); 115 116 // Dynamic module via modulepreload using DOM API 117 link = document.createElement("link"); 118 link.href = "resources/empty_script.js?link-head-modulepreload-dynamic-dom"; 119 link.rel = "modulepreload"; 120 document.head.appendChild(link); 121 122 // Add a style preload with DOM API to be used later 123 link = document.createElement("link"); 124 link.href = "resources/empty_style.css?link-style-preload-used-dynamic"; 125 link.rel = "preload"; 126 link.as = "style"; 127 document.head.appendChild(link); 128 // Use the preload 129 link = document.createElement("link"); 130 link.href = "resources/empty_style.css?link-style-preload-used-dynamic"; 131 link.rel = "stylesheet"; 132 document.head.appendChild(link); 133 134 // Dynamic inline CSS 135 // Add an inline CSS importer 136 document.write(` 137 <style> 138 @import url('resources/empty_style.css?stylesheet-inline-imported-dynamic-docwrite') 139 </style> 140 `); 141 document.write(` 142 <style media=print> 143 @import url('resources/empty_style.css?stylesheet-inline-imported-dynamic-docwrite-print') 144 </style> 145 `); 146 147 // Add a dynamic inline CSS importer using DOM API 148 let style = document.createElement("style"); 149 style.textContent = "@import url('resources/empty_style.css?stylesheet-inline-imported-dynamic-dom')"; 150 document.head.appendChild(style); 151 152 // Add a dynamic render-blocking inline CSS importer 153 style = document.createElement("style"); 154 style.textContent = "@import url('resources/empty_style.css?stylesheet-inline-imported-blocking-render-dynamic-dom')"; 155 style.blocking = "render"; 156 document.head.appendChild(style); 157 158 // Dynamic CSS importer 159 document.write(` 160 <link rel=stylesheet href='resources/importer_dynamic.css'> 161 `); 162 document.write(` 163 <link rel=stylesheet href='resources/importer_print.css' media=print> 164 `); 165 166 // Removing blocking render attribute after request is made 167 const sheet = document.getElementById("link-head-remove-attr"); 168 sheet.blocking = ""; 169 </script> 170 171 <link rel=stylesheet href="resources/empty_style.css?link-style-preload-used"> 172 173 <script> 174 175 const wait_for_onload = () => { 176 return new Promise(resolve => { 177 window.addEventListener("load", resolve); 178 })}; 179 180 promise_test( 181 async () => { 182 const expectedRenderBlockingStatus = { 183 'stylesheet-head-dynamic-docWrite' : 'blocking', 184 'stylesheet-head-dynamic-docWrite-print' : 'non-blocking', 185 'stylesheet-head' : 'blocking', 186 'stylesheet-head-media-print' : 'non-blocking', 187 'stylesheet-head-alternate' : 'non-blocking', 188 'link-style-head-preload' : 'non-blocking', 189 'stylesheet-importer-head' : 'blocking', 190 'stylesheet-head-blocking-render-remove-attr' : 'blocking', 191 'link-head-modulepreload' : 'non-blocking', 192 'stylesheet-inline-imported' : 'blocking', 193 'stylesheet-inline-imported-print' : 'non-blocking', 194 'stylesheet-body': 'non-blocking', 195 'stylesheet-importer-body' : 'non-blocking', 196 'stylesheet-body-media-print' : 'non-blocking', 197 'stylesheet-body-blocking-render' : 'non-blocking', 198 'stylesheet-body-dynamic-docWrite' : 'non-blocking', 199 'stylesheet-body-dynamic-docWrite-print': 'non-blocking', 200 'stylesheet-head-dynamic-innerHTML' : 'non-blocking', 201 'stylesheet-head-dynamic-innerHTML-print' : 'non-blocking', 202 'stylesheet-head-blocking-render-dynamic-innerHTML' : 'blocking', 203 'stylesheet-head-dynamic-dom' : 'non-blocking', 204 'stylesheet-head-blocking-render-dynamic-dom' : 'blocking', 205 'link-style-head-preload-dynamic-dom' : 'non-blocking', 206 'link-head-modulepreload-dynamic-dom' : 'non-blocking', 207 'link-style-preload-used' : 'non-blocking', 208 'link-style-preload-used-dynamic' : 'non-blocking', 209 'link-style-preload-used-immediately' : 'blocking', 210 'link-style-preload-used-immediately-then-preloaded-again' : 'blocking', 211 'stylesheet-inline-imported-dynamic-docwrite' : 'blocking', 212 'stylesheet-inline-imported-dynamic-docwrite-print' : 'non-blocking', 213 'stylesheet-inline-imported-dynamic-dom' : 'non-blocking', 214 'stylesheet-inline-imported-blocking-render-dynamic-dom' : 'blocking', 215 'stylesheet-imported' : 'blocking', 216 'stylesheet-imported-print' : 'non-blocking', 217 'stylesheet-imported-dynamic' : 'non-blocking', 218 'link-image-preload-used-immediately' : 'non-blocking', 219 'link-script-preload-used-immediately' : 'blocking', 220 'link-script-preload-defer-used-immediately' : 'non-blocking' 221 }; 222 223 await wait_for_onload(); 224 225 const entry_list = performance.getEntriesByType("resource"); 226 for (entry of entry_list) { 227 if (entry.name.includes("empty_style.css") || 228 entry.name.includes("importer.css") || 229 entry.name.includes("empty_script.js") || 230 entry.name.includes("blue.png")) { 231 key = entry.name.split("?").pop(); 232 expectedStatus = expectedRenderBlockingStatus[key]; 233 assert_equals(entry.renderBlockingStatus, expectedStatus, 234 `render blocking status for ${entry.name} should be ${expectedStatus}`); 235 } 236 } 237 }, "Validate render blocking status of link resources in PerformanceResourceTiming"); 238 239 </script>