性能检测:performance 对象
Last updated
Was this helpful?
Last updated
Was this helpful?
Performance
对象domReady
vs onload
domReady
是jQuery提供的一个事件。我理解domReady
是对onreadystatechange
事件的封装。核心逻辑即提供一个页面DOM结构稳定之后的事件接口。 可以通过下列代码实现:
不过也有文章指出目前的实现存在一些问题,可以参考DOM Ready 详解 - 张子秋的博客。比如 setTimeout onload 'interactive' 的触发时机均存在不符合预期的情况。
先来看看 MDN 中的定义:
The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading
也就是说浏览器会在 HTML 加载完毕后就会触发该事件,不会等待样式表、图像,以及一些子框架(iframes)的加载完成。
那什么叫"the initial HTML document has been completely loaded and parsed
"呢?我们知道浏览器一般是逐行解析 document 的,所以我 parser 读完最后一行</html>
标签时,HTML 也就加载完了。
不过这里有一个点有待商榷,那就是浏览器真的不会等待样式表的加载完成吗?
Patrick Sexton在"What is domContentLoaded?"中提到了以下四点内容:
domContentLoaded is the point when both the DOM is ready and there are no stylesheets that are blocking JavaScript execution.
This event typically marks when both the DOM and CSSOM are ready
This means that the render tree can now be built
If there is no parser blocking JavaScript then DOMContentLoaded will fire immediately after domInteractive
上述第一点结论明确指出该事件在没有样式表阻塞js执行时,才会触发。根据第四点我们可以知道,所有阻塞 parser 线程的脚本都执行结束后,DOMContentLoaded事件才会触发。也就是说,阻塞 parser 线程的脚本(比如设置了defer
的外部脚本),一定会在DOMContentLoaded之前触发。更准确的说法是:
Scripts with the defer attribute will prevent the DOMContentLoaded event from firing until the script has loaded and finished evaluating.
那这里的样式表有可能阻塞哪里的js代码呢?
这里就需要说说 script 标签了。参考规范对 The script element 标签的定义,满足下图条件的script标签(主要就是defer脚本中的js代码),浏览器会把其中的代码放到一个叫做list of scripts that will execute when the document has finished parsing
的队列当中。
根据事件循环的模型,我们知道 parser 解析 HTML 过程中的 js 代码都是同步执行的,异步执行的代码(ajax请求、定时器等)会被放进事件队列。当 HTML 解析结束后,事件循环会检查事件队列中是否有需要执行的代码,如果有就会开始执行。parser 解析完成后,浏览器会执行一个类似的操作。结合规范中 Parsing HTML document
过程对 the end
环节中一个步骤的定义:
Spin the event loop until the first script in the list of scripts that will execute when the document has finished parsing has its "ready to be parser-executed" flag set and the parser’s Document has no style sheet that is blocking scripts.
可知浏览器结束解析过程后,会检查上述的script队列,如果有待执行的script,则取出并执行。
因此,样式表的加载是有可能阻塞所谓list of scripts that will execute when the document has finished parsing
这个队列中的脚本的。
当 DOMContentLoaded 事件触发后,浏览器还会遍历下面两个队列中的script并执行(如果有)
set of scripts that will execute as soon as possible
该队列中的代码会尽可能快的执行。如添加了async的脚本,会在加载完成后立刻执行。
list of scripts that will execute in order as soon as possible
这里涉及到不同条件的 script,具体可以参考文档。
Patrick Sexton在"What is domComplete?"中指出:
The domComplete time represents the end of the browser processing a document. The browser has received the document, processed it and has done the same for the page subresources like images and CSS.
To a user, this is the point where the browser tab spinner stops spinning. To a developer, this marks the beginning of the time to add additional application logic / javascript.
spec - Parsing HTML documents spec - Scripting speed - performance