浏览器的进程、线程与页面渲染流程

Posted by Mars . Modified at

浏览器渲染基本流程

进程和线程的区别

浏览器线程和进程

浏览器进程?线程?傻傻分不清楚!

进程

什么是进程

进程类似工厂,线程类似工人。

  • 进程是cpu资源分配的最小单位(系统会给它分配内存)。操作系统会为每个进程分配私有、独立的一块内存资源,进程之间互不影响;
  • 当进程被杀掉,分配的内存空间也被释放;
  • 一个进程中可能有一个或多个线程在工作;
  • 同一进程下的各个线程之间,共享系统为该进程分配的同一块内存空间(包括代码段、数据集、堆等);
  • 进程间也可以互相通信,叫做IPC(Inter Process Communication),但是代价较大。

Chrome浏览器主要有哪些进程

浏览器进程

  • 主进程(Browser进程)
    • 与其他进程一起协作,实现浏览器的功能;
    • 负责浏览器界面显示,与用户交互。如前进,后退等;
    • 负责各个页面的管理,创建和销毁其他进程;
    • 将Renderer进程得到的内存中的Bitmap,绘制到用户界面上;
    • 网络资源的管理,下载等。
  • GPU进程:最多一个,用于合成图层、3D图形绘制等。
  • 渲染进程(Renderer进程,也叫浏览器内核)
    • 每个tab页会单独占用一个渲染进程;
    • tab页内的<iframe>也会占用独立的渲染进程;
    • 用于页面渲染、Js执行、事件循环
    • 渲染进程是多线程的,主要有:
      • GUI渲染线程
      • JS引擎线程;
      • 事件触发线程: 管理任务队列;
      • 定时触发器线程;
      • 异步http请求线程;
  • 第三方插件进程 每个第三方插件可能对应一个进程;
  • 实用程序进程: 储存进程、网络进程、音频进程等;

为什么浏览器被设置为多进程

多进程架构的优势

  • 避免单个page crash影响整个浏览器;
  • 避免第三方插件crash影响整个浏览器;
  • 多进程充分利用多核优势;
  • 方便使用沙盒模型隔离插件等进程,为不同进程提供不同的系统访问能力,提高浏览安全和稳定性。

多进程架构的缺陷

浏览器不同进程之间,不能共享同一个内存空间,因此某些基础模块会在不同进程中重复存在,占用额外内存空间。

比如: JS V8引擎在不同的标签页渲染进程的内存空间中都存在。

因此Chrome限制了最大进程数,当进程数达限,Chrome会将访问同一个网站的tab页都放在同一个进程里运行。

线程

线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元。

一个进程可以有多个线程。(进程是工厂,线程是工人)

chromium 官方文档:

chromium线程

每个Chrome进程中含有:

  1. 1个主线程:
    • 在浏览器主进程里:用于更新UI界面;
    • 在渲染进程里:运行大部分Blink代码;
  2. 1个IO线程:
    • 在所有的进程里:所有的IPC message到达此线程;
    • 大部分异步io发生在此线程;
  3. 一些特殊用途线程;
  4. 一个通用线程池。

Chrome浏览器主进程中包含的线程

  • UI线程 : 绘制浏览器顶部按钮和导航栏输入框等组件;
  • 网络线程:管理网络请求;
  • 存储线程:控制文件读写;

Chrome渲染进程中包含的线程

GUI渲染线程(主线程)

数目: 1个。

主要职能:

  1. 初始渲染:解析HTML,解析CSS,构建DOM树,CSSOM树,整合Render树,进行布局和绘制;
  2. 页面发生变化时,执行重绘和重排;
  3. GUI渲染线程JS引擎线程互斥的(不可同时运行)。当 JS 引擎执行时 GUI 线程就会被挂起(相当于被冻结了),GUI 更新会被保存在一个队列中,等到 JS 引擎线程空闲时,再立即取出执行。

JS引擎线程

数目: 1个。

主要职能:

  1. 运行JS引擎(V8):解析JS脚本,运行JS代码;
  2. JS引擎中有一个任务队列,它一直等待任务队列中任务的到来,一旦任务到来立即按序加以处理;
  3. 与GUI渲染线程互斥。(因此Js执行时间如果过长,会导致页面渲染卡顿)

事件触发线程

数目:1个。

主要职能是控制事件循环

  1. 当JS执行遇到宏任务、微任务时,将其加入到事件触发线程的对应队列中;
  2. 事件触发线程会根据任务的执行时机(比如setTimeout宏任务约定的定时时间已到),将任务各自队列中取出,放入JS引擎任务队列中等待执行;
  3. JS引擎会在自己空闲的时候,从队列中依次取出任务执行;

定时触发器线程

主要职能:

  1. 用于setTimeout / setInterval等的计时;
  2. 时间到,则通知事件触发线程,将定时器对应的任务放入Js引擎的任务队列;
  3. HTML标准中要求,低于4ms的定时,时间间隔都算作4ms(也就是定时器最低时间间隔为4ms)。

异步http请求线程

主要职能:

  1. 处理异步http请求;
  2. 请求结果返回,通知事件触发线程,将回调任务放入JS引擎任务队列;

浏览器渲染基本流程

Chrome渲染流程

关键渲染路径:CRP

Browser

  1. 浏览器通过请求得到一个HTML文本;
  2. 渲染进程解析HTML文本,构建DOM树;
  3. 解析HTML的同时,如果遇到内联样式或者样式脚本,则下载并构建样式规则(stytle rules),若遇到JavaScript脚本,则会下载执行脚本;
  4. DOM树和样式规则构建完成之后,渲染进程将两者合并成渲染树(render tree);
  5. 渲染进程开始对渲染树进行布局,生成布局树(layout tree);
  6. 渲染进程对布局树进行绘制,生成绘制记录;
  7. 渲染进程的对布局树进行分层,分别栅格化每一层,并得到合成图层信息;
  8. 渲染进程将合成图层信息发送给GPU进程,GPU进程对各图层进行合成,然后显示页面。

关键渲染路径CRP(Critical Rendering Path),是浏览器将 HTML、CSS、JavaScript 转换为在屏幕上呈现的像素内容所经历的一系列步骤。也就是我们上面说的浏览器渲染流程。

其中有三个关键因素:

  • 关键资源的数量: 可能阻止网页首次渲染的资源;
  • 关键路径长度: 获取所有关键资源所需的往返次数或总时间;
  • 关键字节: 实现网页首次渲染所需的总字节数,等同于所有关键资源传送文件大小的总和。

什么是渲染合成(Composite) ?

合成是一种将页面分成若干层,然后分别对每一层进行光栅化,最后在一个单独的线程 - 合成线程(compositor thread)里面合并成一个页面的技术。

当用户滚动页面时,由于页面各个层都已经被光栅化了,浏览器需要做的只是合成一个新的帧来展示滚动后的效果罢了。

页面的动画效果实现也是类似,将页面上的层进行移动并构建出一个新的帧,交由GPU进行显示即可。

参考资料

窥探现代浏览器架构:1

窥探现代浏览器架构:2

Keywords: Browser
previousPost nextPost
已经有 1000000 个小伙伴看完了这篇推文。