浏览器渲染流程

浏览器输入 URL 至页面最后呈现的过程

  1. 用户输入 URL 地址
  2. 浏览器解析出主机名
  3.  通过查询 DNS 转换为服务器 IP 地址( 按浏览器、本地操作系统、本地 host 文件、路由器、ISP(服务提供商)DNS 缓存、顶级/根 DNS 服务器  逐级查询 DNS 缓存)
    dns-query
  4. 传输层:将 IP 地址端口号解析出来,并与目标 Web 服务器建立 TCP 连接(3 次握手)
  5. 应用层:发送 http 请求,设置好请求行(方法、路径、协议版本)、请求头、空行、请求主体发送请求报文,服务器接收请求后,根据处理结果将响应报文( 响应行、 响应头、 空行、响应主体)返回相关资源给浏览器
  6. 资源请求完毕,关闭连接(4 次挥手),浏览器开始渲染页面

关键渲染路径

关键渲染路径是页面渲染最重要的概念。

关键渲染路径(Critical Rendering Path)是指与当前用户操作有关的内容,具体就是浏览器收到服务器返回的 HTML、CSS 和 JavaScript 等资源并对其进行解析和转变成像素的渲染过程被称为关键渲染路径。

浏览器渲染流程

渲染 5 步流程

  1. 浏览器将 HTML 文档解析成 DOM(Document Obeject Model)树
  2. 处理 CSS 标记,构成层叠样式表模型 CSSOM(CSS Object Model)
  3. 将 DOM 与 CSSOM 合并为渲染树(Render Tree),代表一系列将被渲染的对象
  4. Layout 根据 Render Tree 计算每个节点的信息
  5. Painting 根据计算好的数据绘制整个页面

渲染流程图

  1. WebKit
    webkit
  2. Mozilla’s Gecko
    gecko

回流与重绘

我们都知道 HTML 默认是流式布局的,但 CSS 和 JS 会打破这种布局,改变 DOM 的外观样式以及大小和位置。因此我们就需要知道两个概念:

  • reflow(回流):当浏览器发现某个部分发生了变化从而影响了布局,这个时候就需要倒回去重新渲染,大家称这个回退的过程叫 reflow。 常见的 reflow 是一些会影响页面布局的操作,诸如 Tab,隐藏等。reflow 会从 html 这个 root frame 开始递归往下,依次计算所有的结点几何尺寸和位置,以确认是渲染树的一部分发生变化还是整个渲染树。reflow 几乎是无法避免的,因为只要用户进行交互操作,就势必会发生页面的一部分的重新渲染,且通常我们也无法预估浏览器到底会 reflow 哪一部分的代码,因为他们会相互影响。
  • repaint(重绘):repaint 则是当我们改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸和位置没有发生改变。

需要注意的是,display: none 会触发 reflow,而 visibility: hidden 属性则并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,它会被渲染成一个空框,这在我们上面有提到过。所以 visibility: hidden 只会触发 repaint,因为没有发生位置变化。

我们不能避免 reflow,但还是能通过一些操作来减少回流:

  1. 用 transform 做形变和位移;
  2. 通过绝对位移来脱离当前层叠上下文,形成新的 Render Layer。

另外有些情况下,比如修改了元素的样式,浏览器并不会立刻 reflow 或 repaint 一次,而是会把这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。但是在有些情况下,比如 resize 窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行 reflow。

你的支持将鼓励我继续创作!