跳到主要内容

浏览器组成核心部分 与 职责

总图

  • 浏览器进程
    • 进程管理、导航(前进、后退)、用户交互
  • 网络进程
    • 网络下载功能
  • 渲染进程
    • 通过 HTML CSS JS 渲染成可以显示和交互的页面
    • 资源来自网络下载,不被信任,Chrome会让该进程运行在安全沙箱里
    • GPU 进程
  • 插件进程

从输入内容到页面展示流程

1. 用户输入

  • 输入文字
  • 输入 URL
  • beforeunload
    • 退出前会执行,可以终止导航

2. 网络进程:URL请求过程

  • 重定向(永久重定向301/临时重定向302)
    • 根据 http header 中的 location 来重定向
  • 响应数据类型(http header: Content-Type)处理
    • text/html
    • application/octet-stream: 字节流类型,通常浏览器会按照下载类型, 将请求提交给下载管理器;URL 请求结束

浏览器进程:为页面分配渲染进程

  • 同一站点,复用渲染进程
    • 同一站点:相同协议和根域名
    • eg: 下方三个 URL 都属于同一站点
      https://time.geekbang.org
    https://www.geekbang.org
    https://www.geekbang.org:8080
  • 不同站点,新开页面,重新分配单独的渲染进程

浏览器进程:提交文档

提交文档:

  • 大哥大(浏览器进程)接收到小弟(网络进程)响应头数据后,通知小弟(渲染进程)(提交文档),让其与网络进程建立管道通讯,
  • 收到大哥大的命令,小弟(渲染进程)赶紧与小弟(网络进程)建立数据管道
  • 渲染进程接收完网络进程的数据后,赶紧给大哥大(浏览器进程)汇报(确认提交)
  • 大哥大知道小弟处理好琐事了,开始做小弟们做不了的事,更新浏览器界面状态
    • 安全状态
    • 地址栏 URL
    • 前进后退的历史状态
    • 更新 Web 页面

渲染进程:渲染阶段

  • 将 HTML、CSS、JS 渲染成页面
  • 渲染完成后,通知浏览器进程,停止加载动画

线程

  • 渲染主线程
  • 合成线程

渲染流水线

  • 构建 DOM 树:渲染进程根据 HTML,经由 HTML 解析器,生成 DOM

  • 样式计算:渲染引擎根据 CSS 转换为 styleSheets(document.styleSheets可以获取)

    1. 将 CSS 转为浏览器能够理解的结构

      • CSS 样式主要来源
        • link 外部文件
        • \<style> 标记内的 CSS
        • 元素的 style 属性内嵌的 CSS
    2. 属性值标准化

      • em blue bold 转换标准化
    3. 计算出 DOM 树中每个节点的具体样式

      • CSS 的继承规则

        CSS 属性很多,但并不是所有的属性默认都是能继承父元素对应属性的, 那哪些属性存在默认继承的行为呢?一定是那些不会影响到页面布局的属性,可以分为如下几类:

        • 字体相关:font-family、font-style、font-size、font-weight 等
        • 文本相关:text-align、text-indent、text-decoration、text-shadow、letter-spacing、word-spacing、white-space、line-height、color 等
        • 列表相关:list-style、list-style-image、list-style-type、list-style-position 等
        • 其他属性:visibility、cursor 等

        对于其他默认不继承的属性也可以通过以下几个属性值来控制继承行为:

        • inherit:继承父元素对应属性的计算值
        • initial:应用该属性的默认值,比如 color 的默认值是 #000
        • unset:如果属性是默认可以继承的,则取 inherit 的效果,否则同 initial
        • revert:效果等同于 unset,兼容性差
      • 层叠规则

  • 布局(layout): 根据 DOM 将布局信息保存到布局树中;布局计算;

  • 分层(layers): 渲染引擎为特定的节点生成专用的图层, 并生成对应的图层树(LayerTree)。为了方便一些复杂的3D变换、页面滚动、或者使用z-indexing做z轴排序

    • 布局树和图层树的关系
    • 被提升为单独的一个图层
      1. 拥有层叠上下文属性的元素会被提升为单独的一层:
      • 如果能提前知道对某个元素执行动画操作,那就最好将其标记为 will-change,这是告诉渲染引擎需要将该元素单独生成一个图层
      1. 需要剪裁(clip)的地方也会被创建为图层
  • 为每个图层生成绘制列表绘制指令,并将其提交到合成线程

    绘制列表只是用来记录绘制顺序和绘制指令的列表,而实际上绘制操作是由渲染引擎中的合成线程来完成的

  • 栅格化(raster)操作。用户可视区域一般比图层小,完全渲染图层耗费性能, 将图层划为图块,按照视口(用户看到的部分)附近的图块优先生成位图。所谓的栅格化,就是将图块转换为位图

    渲染进程维护了一个栅格化的线程池,所有的图块栅格化都是在线程池内执行的

    栅格化过程都会使用 GPU 来加速生成,使用 GPU 生成位图的过程叫快速栅格化,或者 GPU 栅格化,生成的位图被保存在 GPU 内存中。

  • 合成和显示:

    • 渲染进程中的合成线程将生成绘制图块的命令(DrawQuad)发送到浏览器进程
    • 浏览器进程viz 的组件执行绘制图块的命令(DrawQuad),将生成的图块保存到内存中,再从内存显示到浏览器页面上

参考:

04 | 导航流程:从输入URL到页面展示,这中间发生了

05 | 渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的?

06 | 渲染流程(下):HTML、CSS和JavaScript,是如何变成页面的?