Loading the DOMContentLoaded Block Page
Please see the code:
<!-- ... --> <head> <style type="text/css"> body { background: gray; } </style> </head> <body> <p> Firefox does not even shows blank page. Tab is stuck in "suggested sites" for 5 seconds. </p> <p> Chrome show just blank white. No text, no background. For 5 seconds. </p> <p> DOMContentLoaded event handler blocks page loading and rendering. Browser does not start rendering page until DOMContentLoaded handler function return. </p> <script> document.addEventListener('DOMContentLoaded', function() { var timestamp = Date.now() + 5000; while (Date.now() < timestamp); // or synchronous 5 seconds XHR as an equivalent of loop }); </script> </body> <!-- ... --> Static html + css is more than enough for rendering content (although without IMG, and good layout blocks are independent of imgs sizes). The overall page layout should be shown immediately, as it was always intended. And only after rendering (or at least starting to draw it) does Javsacript have to work, regardless of whether it just manages click bindings or an infinite loop, as in the example here.
How to start JS after the static page layout is actually displayed, or at least started appearing?
(and a "finished" event is not suitable here, because it is not guaranteed at any reasonable time)
- As you can see from the example, I am not using documentation or planning.
- I also put the script right in front of the body close tag
- I am not doing any real work in the script tag - I am subscribing to the event.
Why does the browser prevent (block) the user from seeing statically defined content? Can at least modern browsers stop this nonsense?
UPD lightening
If you use DOMContentLoaded for common seemingly harmless tasks (related to button events, initializing asynchronous loading of other code, etc.), you actually delay the user from viewing the contents, and this is a real problem with DOMContentLoaded. Locking the loop here is intentional in the example, just to prove that it really is blocking, for those who mistakenly believe that DOMContentLoaded is an “asynchronous” / “non-blocking” safe thing (which is not the case).
Interesting and unexpected. I solved it with requestAnimationFrame (callback), for example:
function foo() { window.requestAnimationFrame(function() { window.requestAnimationFrame(function() { var timestamp = Date.now() + 5000; while (Date.now() < timestamp){}; alert('now'); }); }); } document.addEventListener('DOMContentLoaded', foo);