页面加载原理的应用

load 事件和 DOMContentLoaded 事件的区别

前置

  • CSS 文件下载 不阻塞DOM 树的构建与解析。但是因为浏览器是根据渲染树生成最终页面,而渲染树是由 DOM 树与 CSSOM 树合并而成,那么 CSS 文件的下载与解析将 阻塞 页面的渲染。

  • 阻塞式 JS 文件(即 blocking JS files, 除了具有 asyncdefer 属性的 外联 脚本以外的其他形式脚本)因可能存在查询 DOM 树的语句,那么它一定 阻塞DOM 树的解析构建进程。

    • asyncdefer 属性只对外联脚本生效。

    • JS 下载执行的优先级高于 DOM 树的解析生成是出于避免 DOM 树的构建冲突,并且 一次性(可与 CSSOM 的下载构建优先级高于 JS 脚本执行做对比。) 构建出 DOM 树的目的。

    • 阻塞式 JS 脚本执行之前,其中可能包含查询 CSSOM 的语句,那么阻塞式 JS 脚本执行一定是在 CSSOM 下载并完成构建之后。

    • 阻塞式脚本文件对于 DOMCSSOM 是不同的优先级,这是浏览器的实现,即可理解为 DOM < blocking JSCSSOM > blocking JS,但 DOMCSSOM 二者之间不具有可比性。

那么始终有:

  1. CSS 加载不阻塞 DOM 树的解析构建

  2. CSS 加载阻塞渲染树的解析构建,即阻塞渲染进程

  3. CSS 加载阻塞其后的阻塞式 JS 文件的执行。

注:现代浏览器实现了并发预加载外部依赖,即当 DOM 树解析器被阻塞时,浏览器会识别该阻塞脚本的后续外部依赖进行预加载。但是,后续外部依赖的执行顺序依然是按照原始 DOM 树的结构执行。

HTTP 1.0/1.1 的情况下,Chrome 浏览器 最大同域并发数6。若将部分依赖部署于其他子域时,可扩大当前页面的并发请求为 N*6

因为 HTTP 2 协议建立的单个 TCP 通道实现了并行请求(多路复用链接),而不再是原始的串行请求,那么此时最大同域并发数不再是 6(further reading: HTTP 协议)。

Load 事件

load 事件(触发时机:HTML5 whatwgW3C 5.3 草案 )表示当前页面的 全部 依赖资源加载完时成才会触发事件,包括图片、视频等一切依赖。

DOMContentLoaded 事件

DOMContentLoaded(触发时机:HTML5 whatwgW3C 5.3 草案 )表示在 DOM 树建立完成后就会触发,无需等待样式表MDNJS 高程 p390)、图像等外部资源加载完成。

值得注意的是,当 HTML 中包含阻塞式 JS 脚本时,DOMContentLoaded 需要等到 HTML 中阻塞式脚本执行完成后触发,而阻塞式脚本执行的时机 一定 是在 CSSOM 构建完成之后。

  1. HTML 中不存在阻塞式脚本时,那么 DOMContentLoadedDOM 树被解析构建完成时触发,而不用等待其他如 CSS 等依赖的下载解析完成。

  2. HTML 中存在阻塞式脚本时,那么 DOMContentLoaded 一定是在 JS 脚本执行之后触发,而 JS 可能包含查询 CSSOM 的语句,那么阻塞式 JS 脚本必须阻塞至 CSSOM 构建完成之后执行(与 DOM 的暂停解析不同,CSSOM 的解析构建优先级高于阻塞式 JS 执行)。那么此时, DOMContentLoaded 触发的时机一定是在 CSSOM 完成构建,且阻塞式脚本已经执行完成时(google web fundamentals)。

事件目标的区别

load 事件在 windowdocument 对象上触发。

DOMContentLoaded 事件在 document 对象上触发。

Reference

从输入 url 到得到 HTML 的详细过程

  1. 浏览器根据 DNS 服务器(本地 DNS 优先级最高)得到域名的 IP 地址

  2. 向该 IP 的服务器发送请求(httphttps

  3. 服务端接受请求,处理之后并返回请求

  4. 客户端得到服务端返回的内容