We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
直接使用script脚本的话,html会按照顺序来加载并执行脚本,在脚本加载&执行的过程中,会阻塞后续的DOM渲染。 这是因为 UI 渲染线程与 JS 引擎是互斥的,当 JS 引擎执行时 UI 线程会被挂起。
如果script标签设置了该属性,则浏览器会异步的下载该文件并且不会影响到后续 DOM 的渲染; 如果有多个设置了 defer 的script标签存在,则会按照顺序执行所有的script; defer 脚本会在文档渲染完毕后, DOMContentLoaded 事件调用前执行。
DOM
defer
DOMContentLoaded
async 的设置,会使得script脚本异步的加载并在允许的情况下执行。 async 的执行,并不会按着script在页面中的顺序来执行,而是谁先加载完谁执行。 DOMContentLoaded 事件的调用不会管带有 async 属性的script脚本是否加载完和执行完
async
带有 async 和 defer 的脚本的下载是和 HTML 的下载与解析是并行的,但是 JS 的执行一定是和 UI 线程是互斥的,像下面这张图所示,async 在下载完毕后的执行会阻塞HTML的解析
他们有两处不同:
defer 是会阻塞 DOMContentLoaded 的,被 defer 的脚本要在 DOMContentLoaded 触发前执行,所以如果HTML很快就加载完了(先不考虑 CSS 阻塞 DOMContentLoaded 的情况),而 defer 的脚本还没有加载完,浏览器就会等,等到脚本加载完,执行完,再触发 DOMContentLoaded。
外部样式表并不会阻塞 DOM 的解析,所以 DOMContentLoaded 并不会被它们影响。不过仍然有一个陷阱:如果在样式后面有一个内联脚本,那么脚本必须等待样式先加载完。
简单来说,JS 因为有可能会去获取 DOM 的样式,所以 JS 会等待样式表加载完毕,而 JS 是阻塞 DOM 的解析的,所以在有外部样式表的时候,JS 会一直阻塞到外部样式表下载完毕
<link type="text/css" rel="stylesheet" href="style.css"> <script> // 脚本直到样式表加载完毕后才会执行。 alert(getComputedStyle(document.body).marginTop); </script>
发生这种事的原因是脚本也许会像上面的例子中所示,去得到一些元素的坐标或者基于样式的属性。所以他们自然要等到样式加载完毕才可以执行。
DOMContentLoaded 需要等待脚本的执行,脚本又需要等待样式的加载。
HTML页面的生命周期有以下三个重要事件:
<img>
load
beforeunload/unload
每个时间都有特定的用途:
[译]页面生命周期:DOMContentLoaded, load, beforeunload, unload解析 css加载会造成阻塞吗? 浅谈script标签中的async和defer
The text was updated successfully, but these errors were encountered:
No branches or pull requests
直接使用script脚本的话,html会按照顺序来加载并执行脚本,在脚本加载&执行的过程中,会阻塞后续的DOM渲染。
这是因为 UI 渲染线程与 JS 引擎是互斥的,当 JS 引擎执行时 UI 线程会被挂起。
defer
如果script标签设置了该属性,则浏览器会异步的下载该文件并且不会影响到后续
DOM
的渲染;如果有多个设置了
defer
的script标签存在,则会按照顺序执行所有的script;defer
脚本会在文档渲染完毕后,DOMContentLoaded
事件调用前执行。async
async
的设置,会使得script脚本异步的加载并在允许的情况下执行。async
的执行,并不会按着script在页面中的顺序来执行,而是谁先加载完谁执行。DOMContentLoaded
事件的调用不会管带有async
属性的script脚本是否加载完和执行完注意点
带有
async
和defer
的脚本的下载是和 HTML 的下载与解析是并行的,但是 JS 的执行一定是和 UI 线程是互斥的,像下面这张图所示,async
在下载完毕后的执行会阻塞HTML的解析他们有两处不同:
async
的脚本是优先执行先加载完的脚本,他们在页面中的顺序并不影响执行的顺序defer
的脚本按照他们在页面中出现的顺序依次执行DOMContentLoaded
async
的脚本也许会在页面没有完全下载完之前就加载,这种情况会在脚本很小或本地缓存,并且页面很大的情况下发生defer
的脚本会在页面加载和解析完毕后执行,刚好在DOMContentLoaded
之前执行defer
是会阻塞DOMContentLoaded
的,被defer
的脚本要在DOMContentLoaded
触发前执行,所以如果HTML很快就加载完了(先不考虑 CSS 阻塞DOMContentLoaded
的情况),而defer
的脚本还没有加载完,浏览器就会等,等到脚本加载完,执行完,再触发DOMContentLoaded
。外部样式表并不会阻塞
DOM
的解析,所以DOMContentLoaded
并不会被它们影响。不过仍然有一个陷阱:如果在样式后面有一个内联脚本,那么脚本必须等待样式先加载完。简单来说,JS 因为有可能会去获取 DOM 的样式,所以 JS 会等待样式表加载完毕,而 JS 是阻塞 DOM 的解析的,所以在有外部样式表的时候,JS 会一直阻塞到外部样式表下载完毕
发生这种事的原因是脚本也许会像上面的例子中所示,去得到一些元素的坐标或者基于样式的属性。所以他们自然要等到样式加载完毕才可以执行。
DOMContentLoaded
需要等待脚本的执行,脚本又需要等待样式的加载。HTML 页面的生命周期
HTML页面的生命周期有以下三个重要事件:
DOMContentLoaded
:浏览器已经完全加载了 HTML,DOM 树已经构建完毕,但是像<img>
和样式表等外部资源可能并没有下载完毕;load
:浏览器已经加载了所有的资源(图片,样式表等);beforeunload/unload
:当用户离开页面的时候触发每个时间都有特定的用途:
DOMContentLoaded
:DOM 加载完毕,所以 JS 可以访问所有的 DOM 节点,初始化界面;load
:附加资源已经加载完毕,可以在此事件触发时获得图像的大小(如果没有被在 HTML/CSS 中指定);beforeunload/unload
:用户正在离开页面,可以询问用户是否保存了更改以及是否确定要离开页面。参考资料
[译]页面生命周期:DOMContentLoaded, load, beforeunload, unload解析
css加载会造成阻塞吗?
浅谈script标签中的async和defer
The text was updated successfully, but these errors were encountered: