资讯专栏INFORMATION COLUMN

文档的加载

beita / 1016人阅读

摘要:完成文档和所有子资源已完成加载。在中可以使用事件来检测文档是否加载完毕在更早的版本中可以通过每隔一段时间执行一次来检测这一状态,因为这条代码在加载完毕之前执行时会抛出错误。

Document.readyState

Document.readyState 属性描述了文档的加载状态。当readyState的值变化时,document对象上的readystatechange事件将被触发。

readyState有三类值:
loading / 加载:document 仍在加载。
interactive / 互动:文档已经完成加载,文档已被解析,但是诸如图像,样式表和框架之类的子资源仍在加载。
complete / 完成:文档和所有子资源已完成加载。这个状态表示 load 事件即将被触发。

// 模拟 DOMContentLoaded/ jquery ready
document.onreadystatechange = function () {
  if (document.readyState === "interactive") {
    initApplication();
  }
}

// 模拟 load/onload 事件
document.onreadystatechange = function () {
  if (document.readyState === "complete") {
    initApplication();
  }
}
DOMContentLoaded

当初始HTML文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架完成加载。

DOMContentLoaded支持IE9及以上。在IE8中,可以使用readystatechange事件来检测DOM文档是否加载完毕.在更早的IE版本中,可以通过每隔一段时间执行一次document.documentElement.doScroll("left")来检测这一状态,因为这条代码在DOM加载完毕之前执行时会抛出错误(throw an error)。

浏览器向服务器请求到了 HTML 文档后便开始解析,产物是 DOM(文档对象模型),到这里 HTML 文档就被加载和解析完成了。

当文档中没有脚本时,浏览器解析完文档便能触发 DOMContentLoaded 事件;如果文档中包含脚本,则脚本会阻塞文档的解析,而脚本需要等 CSSOM 构建完成才能执行(因为脚本可能在文档的解析过程中请求样式信息,如果样式还没有加载和解析,脚本将得到错误的值。Firefox在存在样式表还在加载和解析时阻塞所有的脚本,而chrome只在当脚本试图访问某些可能被未加载的样式表所影响的特定的样式属性时才阻塞这些脚本。详见)。在任何情况下,DOMContentLoaded 的触发都不需要等待图片等其他资源加载完成。

defer 和 async

这两个属性都对于内联脚本无作用 (即没有src属性的脚本)。

async:指示浏览器是否在允许的情况下异步执行该脚本。HTML5属性。

defer:被设定用来通知浏览器该脚本将在文档完成解析后,触发 DOMContentLoaded 事件前执行。

区别

同步脚本:

当 HTML 文档被解析时如果遇见(同步)脚本,则停止解析,先去加载脚本,然后执行,执行结束后继续解析 HTML 文档。过程如下图:

带defer :


当 HTML 文档被解析时如果遇见 defer 脚本,则在后台加载脚本,文档解析过程不中断,而等文档解析结束之后,defer 脚本执行。如果有多个defer脚本,会按照它们在页面出现的顺序加载。过程如下图:

带async :

当 HTML 文档被解析时如果遇见 async 脚本,则在后台加载脚本,文档解析过程不中断。脚本加载完成后,文档停止解析,脚本执行,执行结束后文档继续解析。因为有 async 的情况下,JavaScript 脚本一旦下载好了就会执行,所以多个async脚本是不能保证加载顺序的。过程如下图:

defer、async与DOMContentLoaded 的执行顺序

如果 script 标签中包含 defer,在 DOM、CSSOM 构建完毕,defer 脚本执行完成之后,DOMContentLoaded 事件触发。

如果 script 标签中包含 async,HTML文档解析完毕,DOMContentLoaded 事件触发,async 脚本是否执行完毕对其无影响。

参考自:
readyState
DOMContentLoaded

阅读需要支付1元查看
<