DOMContentLoaded阻止页面加载

时间:2015-09-18 16:12:20

标签: javascript dom

请见代码:

<!-- ... -->
<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>
<!-- ... -->

静态html + css足以呈现内容(虽然没有IMG,但是好的布局块不依赖于imgs大小)。一般页面布局应该像它一直想要的那样立即显示。 只有在渲染(或者至少开始绘制它)之后,Javsacript才能运行,无论是否只是控制点击绑定或无限循环,如下例所示。

如何在实际呈现静态页面布局之后运行JS,或者至少开始显示?

(并且“就绪”事件不适合此处,因为不保证在任何合理的时间内开火)

  • 正如您从示例中看到的那样,我没有使用文档写入或计划。
  • 我还在正文结束标记
  • 之前放置脚本
  • 我没有在脚本标签中做任何实际的工作 - 我参加了活动。

为什么浏览器会阻止(阻止)用户查看静态定义的内容?至少现代浏览器可以阻止这种废话吗?

UPD。的澄清

如果你使用DOMContentLoaded进行常规的看似无害的任务(包括按钮事件,初始化其他代码的异步加载等),你实际上是在推迟用户查看内容,这是DOMContentLoaded的真正问题。这里的循环阻塞是有意的,只是为了证明它确实阻塞了,对于那些错误地认为DOMContentLoaded是“异步”/“非阻塞”安全的东西(不是)。

1 个答案:

答案 0 :(得分:3)

有趣且意外。我用requestAnimationFrame(回调)解决了它,如下所示:

function foo() {
    window.requestAnimationFrame(function() {
        window.requestAnimationFrame(function() {
            var timestamp = Date.now() + 5000; while (Date.now() < timestamp){};
            alert('now');
        });
    });
}
document.addEventListener('DOMContentLoaded', foo);