延迟脚本在DOMContentLoaded事件之前执行? [英] Are deferred scripts executed before DOMContentLoaded event?

查看:214
本文介绍了延迟脚本在DOMContentLoaded事件之前执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

延迟安排



但Google在技术上不正确。内部JavaScript在CSSOM准备就绪之前被执行。从我的测试中,我发现MDN是正确的,如果js文件(延迟和非延迟)在css文件(或js是内联)之前被下载,那么js在CSSOM准备好之前被执行。所以js可能会错误地处理样式。为了避免在所有js逻辑之前需要强制回流。



所以如果用户访问我们的网站,所有需要的js已经被缓存,并且css没有被缓存,或者js在css之前被下载,那么他可能会看到错误地呈现的页面。为了避免这种情况,我们应该在我们所有网站的js文件中添加强制回流。

解决方案

DOMContentLoaded 可以在CSSOM之前被解雇,



Google Developer上的文章描述了 async 而不是 defer ,但在您的问题的情况下,它不会改变任何内容,因为根据


Upon defer attirbute MDN says:

This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded. The defer attribute should only be used on external scripts.

On DOMContentLoaded MDN also says:

The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets...

So DOMContentLoaded is fired before CSSOM is ready. This means deferred scripts are executed before CSSOM is ready. But if thats true the scrips must not be able to get correct css property values and must not apply css correctly. But it's not true, we know all deferred scripts work well.

  1. So is MDN documentation technically incorrect?
  2. Where can I find the official documentation of DOMContentLoaded`? I searched in https://dom.spec.whatwg.org/ but couldn't find it.

P.S: Please not that google says that CSSOM is build before executing any inline javscript

But google is technically incorrect. Inline JavaScript gets executed before CSSOM is ready. And from my tests I found that MDN is correct and if js files(both deferred and non-deferred) are downloaded before css files(or js is inline) then js is executed before CSSOM is ready. So js might handle styles incorrectly. To avoid that we need a force reflow before all js logic.

So if a user visits our website with all js required already cached and css not cached OR js gets downloaded before css then (s)he might see incorrectly rendered page. To avoid this we should add force reflow in all our websites' js files.

解决方案

DOMContentLoaded can be fired before CSSOM, source

The domContentLoaded event fires shortly after the HTML is parsed; the browser knows not to block on JavaScript and since there are no other parser blocking scripts the CSSOM construction can also proceed in parallel.

Article on Google Developer describes async instead of defer but in the case of your question, it doesn't change anything because based on Steve Sourders article on perfplanet

DEFER scripts execute after DOM Interactive.

and his comment under his article

[...] the spec says that DEFER scripts run after domInteractive but before domContentLoaded.

You can make your own experiment, look below for code using defer and timeline

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.3/angular-material.css">
</head>
<body>
  <h1>App</h1>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/js/bootstrap.js" defer></script>
</body>
</html>

这篇关于延迟脚本在DOMContentLoaded事件之前执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆