There is a similar question that wasn’t resolved.
I’ve encountered a situation when handler that listens to DOMContentLoaded can block first paint. Sometimes it blocks, sometimes it doesn’t
I tried many times cmd + R to see it. Is there any explanation to this behaviuor?
Also I recordered a video to show this: https://www.youtube.com/watch?v=EDZQ1nLCK2w&feature=youtu.be
- When you see a blank page after reload then it means DOMContentLoaded blocked first paint
- When you see the text “Some text” and then a blank page after reload it means DOMContentLoaded didn’t block first paint
window.addEventListener('DOMContentLoaded', () => { let i = 0; while (i++ < 1000000000) { continue; } document.getElementById('el').remove(); });
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <p id="el">Some text</p> </body> </html>
Advertisement
Answer
I figured it out. There is a bug in Blink rendering engine that dispatches DOMContentLoaded event synchronously
// #blink/renderer/core/dom/document.cc // #blink::Document::FinishedParsing // FIXME: DOMContentLoaded is dispatched synchronously, but this should be // dispatched in a queued task, see https://crbug.com/425790 if (document_timing_.DomContentLoadedEventStart().is_null()) document_timing_.MarkDomContentLoadedEventStart(); DispatchEvent(*Event::CreateBubble(event_type_names::kDOMContentLoaded)); if (document_timing_.DomContentLoadedEventEnd().is_null()) document_timing_.MarkDomContentLoadedEventEnd(); SetParsingState(kFinishedParsing);
** Why it sometimes was dispatched asynchronously I don’t know. Now, on my side, it’s always synchronous (probably there was one more bug at the time question was asked)