Skip to content

Chrome 架构 ​

进程与线程 ​

每一个执行中的程序可以理解为 进程, 一个进程由多个线程组成

一个进程中任意一个线程出错, 就会导致整个进程出错

一个进程中的所有线程共享进程中的数据

不同进程之间的内容相互隔离

关闭进程时, 进程中的所有线程也会关闭

进程 ​

进程是 CPU 资源分配的最小单位

线程 ​

线程是 CPU 调度的最小单位

区别 ​

  1. 进程是资源分配的最小单位, 线程是程序执行的最小单位

  2. 进程有自己的独立地址空间, 每启动一个进程, 系统就会为它分配地址空间, 建立数据表来维护代码段、堆栈段和数据段, 这种操作非常昂贵. 而线程是共享进程中的数据的, 使用相同的地址空间, 因此 CPU 切换一个线程的花费远比进程要小很多, 同时创建一个线程的开销也比进程要小很多

  3. 线程之间的通信更方便, 同一进程下的线程共享全局变量、静态变量等数据, 而进程之间的通信需要以通信的方式(IPC)进行. 不过如何处理好同步与互斥是编写多线程程序的难点

  4. 但是多进程程序更健壮, 多线程程序只要有一个线程死掉, 整个进程也死掉了, 而一个进程死掉并不会对另外一个进程造成影响, 因为进程有自己独立的地址空间

单进程浏览器架构 ​

进程包含 网络、插件、js 运行环境、渲染引擎等模块

缺点 ​

  • 不稳定

一个模块的崩溃会引起整个浏览器的崩溃

  • 不流畅

  • 不安全

多进程浏览器架构 ​

最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程

浏览器进程 ​

界面显示、用户交互、子进程管理, 同时提供存储等功能

渲染进程 ​

核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页, 排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中, 默认情况下, Chrome 会为每个 Tab 标签创建一个渲染进程. 出于安全考虑, 渲染进程都是运行在沙箱模式下

渲染进程中的几种线程:

  • 主线程

    主线程是浏览器渲染进程中最重要的线程之一, 负责处理用户输入、执行 JavaScript 代码、更新 DOM 和样式信息等任务. 在主线程中运行的任务会按照事件循环模型依次执行, 确保页面的交互和渲染能够顺利进行

  • 渲染线程

    渲染线程负责将 HTML、CSS 和 JavaScript 转换为可视化页面, 包括布局计算、绘制和合成图层等操作. 在渲染线程中, 会生成页面的渲染树(Render Tree), 并使用 GPU 进行加速渲染

  • 定时器线程

    定时器线程用于处理通过 setTimeout 和 setInterval 等方法设置的定时任务. 它负责在指定时间后将任务添加到主线程的任务队列中执行

  • 事件线程

    事件线程用于处理各种事件, 如鼠标点击、键盘输入等用户交互事件. 当事件发生时, 会被添加到事件队列中, 在主线程空闲时被依次处理

GPU 进程 ​

UI 界面都选择采用 GPU 来绘制

网络进程 ​

主要负责页面的网络资源加载, 之前是作为一个模块运行在浏览器进程里面的, 直至最近才独立出来, 成为一个单独的进程

插件进程 ​

主要是负责插件的运行, 因插件易崩溃, 所以需要通过插件进程来隔离, 以保证插件进程崩溃不会对浏览器和页面造成影响

渲染流程 ​

整个渲染流程分为: 构建 DOM 树、样式计算、布局阶段、分层、绘制、分块、光栅化和合成

  • 构建 DOM 树

    解析 HTML 文件转换为 DOM 树

  • 构建 CSSOM 树

    解析 CSS 文件, 构建 CSSOM 树

  • 布局

    将 DOM 树和 CSSOM 树合成 渲染树, 其中只需要包含显示的节点和样式信息

  • 分层

    对渲染树进行分层操作, 生成分层树

  • 图层绘制

    对每个图层生成绘制列表, 提交到合成线程

  • 栅格化

    合成线程将图层分成不同的图块, 并通过栅格化将图块转化为位图

  • 合成与显示

    合成线程给浏览器进程发送绘制指令

重绘 ​

当计算好盒模型的位置、大小及其他属性后, 浏览器根据每个盒子特性进行绘制

元素绘制属性变化, 触发重绘, 重绘省去了布局和分层阶段,执行效率高于重排

  • 颜色的修改
  • 文本方向的修改
  • 阴影的修改

直接合成阶段 ​

无需布局和绘制, 只执行合成操作

其他 ​

script defer async

:name