Skip to main content

浏览器内核

对于浏览器的每个标签页都有属于自己的浏览器内核实例。而浏览器内核的主要功能是通过取得页面内容、整理信息(应用 CSS)、计算和组合最终输出可视化的图像结果,因此也被称为渲染引擎(渲染进程)。

浏览器内核划分:

  • GUI 渲染线程
  • JavaScript 引擎线程
  • 定时触发器线程
  • 事件触发线程
  • 异步 http 请求线程

GUI 渲染线程​

  • 负责渲染浏览器界面,解析 HTML,CSS,构建 DOM 树、CSS 规则树以及渲染树,布局和绘制等。
  • 当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行
  • GUI 渲染线程与 JS 引擎线程是互斥的,当 JS 引擎执行时 GUI 线程会被挂起(相当于被冻结了),GUI 更新会被保存在一个队列中等到 JS 引擎空闲时立即被执行。

JavaScript 引擎线程​

Javascript 引擎,也可以称为 JS 内核,主要负责处理 Javascript 脚本程序,例如 V8 引擎。Javascript 引擎线程理所当然是负责解析 Javascript 脚本,运行代码

定时触发器线程​

setInterval 与 setTimeout 所在线程,浏览器定时计数器并不是由 JavaScript 引擎计数的, 因为 JavaScript 引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确, 因此通过单独线程来计时并触发定时是更为合理的方案。

事件触发线程​

当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待 JS 引擎的处理。这些事件可以来自定时任务、也可来自浏览器内核的其他线程如鼠标点击、AJAX 异步请求等,但由于 JS 的单线程关系所有这些事件都得排队等待 JS 引擎处理。

异步 http 请求线程​

在 XMLHttpRequest 在连接后是通过浏览器新开一个线程请求, 将检测到状态变更时,如果有回调函数,异步线程就产生状态变更时将事件放到 JavaScript 引擎的处理队列中等待处理。

GUI 渲染线程与 JS 引擎线程互斥​

js 引擎线程在渲染的时候,很可能会执行一些 DOM 操作等,此时如果 GUI 渲染线程与 JS 引擎线程不互斥,那么当 JS 引擎执行一些 DOM 操作后会给 GUI 渲染线程的渲染带来迷惑,例如 GUI 渲染 id= ‘robbie’的 DOM 节点 div,此时 JS 线程却是要删除此节点,那么就会造成一种混乱,不知道该如何操作。为了渲染结果的一致性,GUI 渲染线程与 JS 引擎线程被设定是互斥的,当 JS 引擎执行时 GUI 线程会被挂起(相当于被冻结了),GUI 更新会被保存在一个队列中等到 JS 引擎空闲时立即被执行。

JS 的阻塞页面渲染​

在默认情况下,js 的下载、解析和执行阶段都会阻塞页面的执行。由上面的内容可知 GUI 渲染线程与 JS 引擎线程互斥,所以在 JS 执行的时候,GUI 线程会被挂起。所以在代码中我们要尽量的将 JS 写在后面,等 DOM 执行完才执行。如果写在 DOM 树构建之前会加长白屏的时间。