文章

从URL到页面渲染过程

  1. 浏览器解析URL

  2. 浏览器检查是否有缓存

  3. DNS解析(迭代)

    1. 客户端向本地域名服务器发送域名解析请求,成为本地域名服务器的一个客户
    2. 本地域名服务器向根域名服务器查询
    3. 本地域名服务器向顶级域名服务器查询
    4. 本地域名服务器向二级域名服务器查询
    5. 本地域名服务器向权限域名服务器查询,得到服务器的ip地址。
    6. 本地域名服务器将查询结果返回给客户端

    DNS查询有迭代和递归两种方式,并且发送的数据单元是UDP(为了节省资源)

  4. 客户端与服务器建立TCP连接(三次握手)

    1. 客户端发送SYN报文给服务器
    2. 服务器返回SYN-ACK报文
    3. 客户端返回ACK报文

    三次握手的作用有二:一是为了验证双方的发送和接收能力,二是为了避免建立无效的TCP连接。

  5. 客户端发送HTTP请求

  6. 服务器接收处理后发送响应报文

  7. 客户端接收后浏览器进行页面渲染

    1. 将HTML解析为DOM树,加载子资源。
    2. 样式计算。生成每个节点的计算样式
    3. 布局。遍历DOM树和计算样式来创建布局树,布局树上包含所有页面上存在的节点的几何属性和样式。
    4. 绘制。遍历布局树生成绘制记录。
    5. 合成。遍历布局树来生成层树,将页面分割为不同的图层,然后将图层分别进行栅格化,然后合成器合成帧并渲染出来,当页面滚动时移动图层合成新的帧来生成滚动动画。

    详细流程:

  8. 解析HTML,构建DOM树。此阶段又分为 标记化阶段建树阶段

    1. 标记化阶段。遇到<就进入标记打开状态,然后进入标签名称状态记录[a-z]直到遇到>,进入数据状态,遇到</切换到结束标记打开状态,随后进入标记名称状态,遇到>回到数据状态。参考
    2. 建树阶段。通过之前标记化阶段获得的标记信息,构建对应的DOM对象,并将DOM对象添加到DOM树中。
  9. 样式计算。此阶段会做三件事:格式化样式表、标准化样式属性、计算节点样式。

    1. 格式化样式表。在此阶段会将css样式转换成一个结构化对象styleSheets,在浏览器控制台能够通过document.styleSheets查看
    2. 标准化样式属性。将一些样式的数值转换成引擎能够理解的值,例如将emrem转换为px,将boid转换为700
    3. 计算阶段样式。计算每个节点的样式,如果没有样式则会使用浏览器默认样式,计算过程中会运用层叠继承规则。
  10. 生成布局树。遍历DOM数的节点并计算节点的样式和几何属性。布局树上有所有可见的元素,包括伪元素,但是不包括display:none的元素。

  11. 生成图层树。浏览器会遍历布局树来将页面分隔为不同的层,一般来说节点的图层默认是父节点的图层,但是拥有层叠上下文的节点会被提升为单独的一层。

  12. 生成绘制列表。渲染引擎将图层分解成一个个的绘制指令,比如先画背景,在描绘边框…然后将这些指令按顺序合成一个待绘制列表。

    一个块渲染对象的堆栈顺序是:

    1. 背景色

    2. 背景图

    3. border

    4. children

    5. outline

  13. 栅格化。合成线程将图层分为不同的图块,并按照绘制列表绘制图块。然后合成线程将离视口近的图块交给栅格化线程进行栅格化来生成位图,最后将生成的位图交给合成线程。

  14. 显示器显示内容。合成线程通知浏览器进程,浏览器进程将页面内容发送给GPU来显示到屏幕上。

浏览器的多进程架构

浏览器是多进程的。

  • 浏览器进程:处理地址栏、书签栏、网络请求等操作。
    • UI线程:控制浏览器的按钮及输入框
    • 网络线程:处理网络请求
    • 存储线程:控制文件等访问
  • 渲染进程:负责一个标签页中有关页面渲染的所有事情。
    • 一个主线程
    • 多个工作线程
    • 一个合成器线程
    • 多个栅格化线程
  • 插件进程:控制一个网页中的所有插件。
  • GPU进程:处理CPU相关任务
  • 其他进程

线程和进程的区别

进程是程序的一次执行过程,是CPU的资源分配的最小单位,进程由进程控制块、数据段和程序段组成,进程包含三种状态:就绪、运行、阻塞。

线程是进程的执行单位,一个进程可以拥有一个或多个线程,线程共享进程的内存,并且线程之间的切换开销较小。