remove-attr-unblocks-rendering.optional.html (3362B)
1 <!DOCTYPE html> 2 <title>Removing `blocking=render` should unblock rendering</title> 3 <link rel="help" href="https://html.spec.whatwg.org/C/#blocking-attribute"> 4 <link rel="help" href="https://html.spec.whatwg.org/C/#rendering-opportunity"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="support/test-render-blocking.js"></script> 8 9 <!-- 10 The test is marked "optional" because even when the document is no longer 11 render-blocked, the user agent is still free to take other factors, which are 12 not limited by the spec, into consideration and therefore decide not to 13 render. However, it is still more desirable if rendering starts 14 immediately/soon. 15 --> 16 17 <script class="test" data="parser-inserted async script" async blocking="render" 18 src="support/dummy-1.js?pipe=trickle(d1)&async"></script> 19 <script class="test" data="parser-inserted defer script" defer blocking="render" 20 src="support/dummy-1.js?pipe=trickle(d1)&defer"></script> 21 <script class="test" data="parser-inserted module script" type="module" 22 blocking="render" src="support/dummy-1.mjs?pipe=trickle(d1)"></script> 23 <script class="test" data="parser-inserted async module script" type="module" 24 async blocking="render" src="support/dummy-1.mjs?pipe=trickle(d1)&async"></script> 25 26 <!-- 27 No test for parser-inserted stylesheets and synchronous scripts because they 28 are render-blocking by default, so removing `blocking=render` does not unblock 29 rendering. 30 --> 31 32 <script> 33 function addRenderBlockingElement(tag, title, attributes, optional_text) { 34 let element = document.createElement(tag); 35 element.className = 'test'; 36 element.setAttribute('data', title); 37 element.blocking = 'render'; 38 Object.assign(element, attributes); 39 if (optional_text) 40 element.textContent = optional_text; 41 document.head.appendChild(element); 42 } 43 44 addRenderBlockingElement( 45 'link', 'script-inserted stylesheet link', 46 {rel: 'stylesheet', blocking: 'render', href: 'support/target-red.css?pipe=trickle(d1)&dynamic'}); 47 48 addRenderBlockingElement( 49 'script', 'script-inserted script', 50 {src: 'support/dummy-1.js?pipe=trickle(d1)&dynamic'}); 51 addRenderBlockingElement( 52 'script', 'script-inserted module script', 53 {type: 'module', src: 'support/dummy-1.mjs?pipe=trickle(d1)&dynamic'}); 54 55 addRenderBlockingElement( 56 'style', 'script-inserted inline style', {}, 57 '@import url("support/target-red.css?pipe=trickle(d1)&imported&dynamic")'); 58 </script> 59 60 <div id="dummy">Some text</div> 61 62 <script> 63 const testElements = [...document.querySelectorAll('.test')]; 64 const loadObservers = testElements.map(element => new LoadObserver(element)); 65 66 promise_setup(async () => { 67 for (let element of testElements) 68 element.blocking = ''; 69 70 // Test cases are run after rendering is unblocked. 71 await new Promise(resolve => requestAnimationFrame(resolve)); 72 }); 73 74 for (let index = 0; index < testElements.length; ++index) { 75 promise_test( 76 async () => assert_false(loadObservers[index].finished), 77 'Render-blocking on ' + testElements[index].getAttribute('data') + ' is cancellable'); 78 } 79 80 for (let index = 0; index < testElements.length; ++index) { 81 promise_test( 82 () => loadObservers[index].load, 83 'Loading of ' + testElements[index].getAttribute('data') + ' should eventually succeed'); 84 } 85 </script>