浅谈浏览器页面渲染过程 load 与 DOMContentLoa

2020-02-10  本文已影响0人  再次重逢的时间
封面

一个问题

为什么推荐把 <script> 都放在 <body> 底部?

正文

document.readyState

该属性描述了文档的加载状态,发生变化时,会在 document 对象上触发 readystatechange 事件。有3种状态:

浏览器页面渲染过程

  1. 浏览器与服务器建立 TCP 连接发送 HTTP 请求,获取 HTML 文档并开始从上到下解析,构建 DOM
  2. 在构建 DOM 过程中:
    • 如果遇到外联的 css 文件,下载文件并执行构建 CSSOM,此过程不影响 DOM 构建,但在完成之前会阻止页面渲染。
    • 如果遇到外联的 js 文件,则暂停构建 DOM
      • 若在这之前的 css 文件已加载完毕且 CSSOM 构建完成,则合并已经构建好的 DOMCSSOM 并渲染到页面上
      • 之后等 js 文件下载并执行后,然后继续构建后边的 DOM
  3. 完成文档解析后,将 DOMCSSOM 进行关联和映射,生成 Render Tree 渲染页面。
  4. 当所有同步的 js 代码执行完毕后,会在 documentwindow 对象上触发 DOMContentLoaded 事件,此时对应 document.readyState === 'interactive'
  5. 当所有资源完成加载后,会在 window 对象上触发 load 事件,此时对应 document.readyState === 'complete'

在这个过程中,js 文件的下载和执行会阻塞文档的解析,这也就是为什么推荐把 <script> 都放在 <body> 底部,下文中还将介绍更优雅的实现方式。

小结

关于文件加载

浏览器对同一域名下的资源并发下载线程数是有限的,比如 chrome 为6个。
因此建议对于文件请求并发量比较大的页面,把静态资源尽可能放在不同的域名下,一方面尽可能多的加大并发请求数量,另一方面避免静态资源请求与数据请求在同一主域名下导致静态资源请求携带 cookie 造成不必要的带宽浪费。

script 的 defer 与 async 属性

上文中提到 js 文件的下载和执行会阻塞文档的解析,推荐把 <script> 都放在 <body> 底部,此处给出更优雅的解决方式。

参考文章

再谈 load 与 DOMContentLoaded

浅谈script标签的defer和async

document.readyState [MDN]

上一篇 下一篇

猜你喜欢

热点阅读