问题描述
延迟安排
但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:
On DOMContentLoaded
MDN also says:
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.
- So is MDN documentation technically incorrect?
- 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
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
and his comment under his article
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事件之前执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!