这是我参与「第四届青训营 」笔记创作活动的的第13天
浅析DOMContentLoaded
什么是DOMContentLoaded
MSN对此的介绍:DOMContentLoaded - Web API 接口参考
简而言之:初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发。
如图,红色箭头指向为DOMContentLoaded,蓝色箭头指向为Load
DOMContentLoaded和Load区别
- DOMContentLoaded 在 HTML 文档本解析之后触发
- Load 是在 HTML 所有相关资源(包括图片等其他静态资源)被加载完成后触发。
你可以打开这个网站(刷新页面前请在网络中打开
禁用缓存):DOMContentLoaded和Load区别
网页的加载速度
谈起网页加载速度,你觉得衡量其的指标是什么?是网页加载完全部内容的时间吗?
举个例子:当你打开这篇文章时,首先映入眼帘的可能是大量的文字,而图片资源还没有加载出来。此时你已经能够正常阅读这篇博客的内容了,或许图片资源的加载对于文章的阅读并不是特别着急。因此,总结一下:
在对图片(静态)资源的及时性不敏感情况下,页面的加载速度的衡量指标可以转化为从页面空白到出现内容花费的时间。即一个HTML文档加载和解析的时间。
触发时间
如图所示,浏览器的渲染引擎在加载并解析完HTML文档后,会生成DOM。此刻便会触发DOMContentLoaded。
但上述情况并未考虑引入 JS 脚本的情况。
JavaScript 可以阻塞 DOM 的生成,当浏览器解析 HTML 文档时,如果遇到 JavaScript 脚本,便会停下对 HTML 文档的解析,转而去处理脚本。如果脚本是内联的,浏览器会先去执行这段内联的脚本,如果是外链的,那么先会去加载脚本,然后执行。在处理完脚本之后,浏览器便继续解析 HTML 文档。
<body>
<script>
console.log(document.getElementById('btn')); // null
</script>
<button id="btn"></button>
<script type="text/javascript">
console.log(document.getElementById('btn')); // <button id="btn"></button>
</script>
</body>
另外,JavaScript 可以查询对象的样式。因此,在 CSS 解析完成,也就是 CSSOM 生成之后,JavaScript 才可以被执行。
异步脚本
HTML5 中定义了两个定义异步脚本的方法:defer 和 async。对应的加载时间如可参考:什么时候执行DOMContentLoaded - 掘金 (juejin.cn)
总结
DOMContentLoaded 时间是前端性能监控的一个重要指标,理解其运行机制对于计算和运用有重要意义。