Skip to content

Latest commit

 

History

History
81 lines (73 loc) · 5.16 KB

File metadata and controls

81 lines (73 loc) · 5.16 KB

用户输入地址到页面展示,发生了什么?

03.png

  1. 用户输入地址后,浏览器利用自身默认的搜索引擎判断输入的是url还是其他内容。
  2. 如果是url地址,便会发起页面请求。

02.png

// curl -I https://time.geekbang.org/ 获取服务端响应信息
// 浏览器进程通过进程间通信(IPC)将 url 交给网络进程,网络进程首先查找本地缓存是否缓存了该资源,如果有就直接返回。如果没有,进入请求流程。
// 查询 DNS 缓存,没有就通过域名服务解析拿到具体的 IP 地址。
// 建立 TCP 连接,如果是 HTTPS 请求,还需要建立 TLS 连接。
// 构建请求行、请求头,向服务器发送 http 请求
// 服务器接收请求,根据请求信息生成相应数据,构建响应行、响应头返回给浏览器网络进程
  1. 准备渲染进程
// 默认情况下,一个标签一个渲染进程(属于同一站点的网页--根域名、http协议相同,共享一个渲染进程。不过可以在页面跳转时指定 rel="noopener noreferrer" 从而新开一个渲染进程)
// 使用同一个渲染进程的条件
// 首先 A 标签页和 B 标签页属于同一站点,其次 A 标签页和 B 标签页需要有连接关系(通过页面间跳转打开的)。
// 页面跳转时指定 rel="noopener noreferrer" 从而新开一个渲染进程。
  1. 提交文档 “文档”是指 URL 请求的响应体数据。
// “提交文档”的消息是由浏览器进程发出的,渲染进程接收到“提交文档”的消息后,会和网络进程建立传输数据的“管道”。
// 等文档数据传输完成之后,渲染进程会返回“确认提交”的消息给浏览器进程。
// 浏览器进程在收到“确认提交”的消息后,会更新浏览器界面状态,包括了安全状态、地址栏的 URL、前进后退的历史状态,并更新 Web 页面。
  1. 渲染阶段
  • 构建 DOM 树 html解析器(HTMLParser)将 html 解析成 DOM 树。
// 前提
// 网络进程接收到响应头之后,根据响应头中的 content-type 判断是否为 html 类型
// 是的话,为该请求选择或者创建一个渲染进程。渲染进程准备好之后,网络进程和渲染进程之间会建立一个共享数据的管道
// 然后就可以一边传输字节流一边解析 dom 了
// 开始解析
// 首先通过分词器将字节流转换为 Token(tag token 和 文本 token)。
// 然后需要将 Token 解析为 DOM 节点,并将 DOM 节点添加到 DOM 树中。
// HTML 解析器维护了一个Token 栈结构,通过解析 StartTag Token 和 EndTag Token,不停地进行压栈和出栈,直到解析完毕。

JavaScript 文件的下载过程会阻塞 DOM 解析。如果 JavaScript 文件中没有操作 DOM 相关代码,就可以将该 JavaScript 脚本设置为异步加载,通过 async 或 defer 来标记代码。使用 async 标志的脚本文件一旦加载完成,会立即执行;而使用了 defer 标记的脚本文件,需要在 DOMContentLoaded 事件之前执行。 css 文件会阻塞 JavaScript 的执行(不阻塞下载),css 下载会阻塞 dom 的解析。

  • 样式计算,构建 styleSheets
// 将 css 转化为 styleSheets(document.styleSheets)。
// 将 css 属性值转化为标准属性值(px等)。
// 计算出 DOM 树中每个节点的具体样式(css 继承等)。
  • 布局树

05.png

// 根据 dom 树和 styleSheets,构建一棵只包含可见元素的布局树(不包含 display:none 等)。
// 计算布局树节点的几何坐标位置
  • 对布局树进行分层,并生成分层树。 为了实现一些复杂的 3D 变换、页面滚动,或者使用 z-indexing 做 z 轴排序等,渲染引擎会为特殊节点进行分层。
// 拥有层叠上下文属性(明确定位属性的元素、定义透明属性的元素、使用 CSS 滤镜的元素等)的元素会被提升为单独的一层。
// 需要剪裁(clip)的地方也会被创建为图层(如滚动条)。
  • 图层绘制、合成、显示 为每个图层生成绘制列表,并将其提交到合成线程。
  • 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
  • 合成线程发送绘制图块命令 DrawQuad 给浏览器进程。
  • 浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。

浏览器页面加载的阶段

  • 浏览器发起请求,提交数据,此时页面还是上一个页面的内容。对应至上面的提交文档阶段。

  • 解析白屏,此时页面空白,等待生成布局树,准备首次渲染。

    解析HTML、下载 CSS、下载 JavaScript、生成 CSSOM、执行 JavaScript、生成布局树、绘制页面一系列操作。

    • 通过内联 JavaScript、内联 CSS 来移除这两种类型的文件下载,这样获取到 HTML 文件之后就可以直接开始渲染流程了。
    • 减小文件大小
    • 异步加载 js
  • 页面绘制。