揭秘浏览器是如何控制JS执行的

88 阅读3分钟

理解本文需要先知道js的事件机制,可以先看这篇文章:(juejin.cn/post/752564…)

揭秘浏览器内核:多进程架构与异步机制深度解析

现代浏览器是一个复杂而高效的系统,它利用多进程架构来确保性能、稳定性和安全性。理解浏览器的内部工作原理,尤其是其多线程模型和事件循环机制,是掌握前端性能优化的关键。


浏览器多进程架构概览

以 Chrome 为代表的现代浏览器采用多进程架构,将不同的功能模块隔离在独立的进程中。这种设计带来的主要优势是:即使某个标签页崩溃(一个进程),也不会影响到整个浏览器或其他标签页(其他进程)的运行。

主要的进程包括:

  • 浏览器主进程 (Browser Process): 负责用户界面(地址栏、书签等)、网络请求、文件访问以及管理其他子进程。
  • 渲染进程 (Renderer Process): 通常每个 Tab 或一组 Tab 拥有一个独立的渲染进程。这是执行 JavaScript、渲染网页、处理布局和绘制的核心。
  • GPU 进程 (GPU Process): 负责 3D 渲染和高性能图形处理。
  • 插件进程 (Plugin Process): 管理浏览器插件(如早期的 Flash)。

JavaScript 代码执行由渲染进程负责

在这些进程中,渲染进程是网页内容的核心执行环境。渲染进程又有多个线程。


渲染进程中的五大关键线程

在渲染进程内部,有多个线程协同工作,共同完成网页的加载、渲染和脚本执行。理解这些线程的角色至关重要:

1. 渲染进程的主线程 (GUI 渲染线程)

这是渲染进程的核心线程,负责网页的渲染工作:

  • 解析 HTML (生成 DOM 树)。
  • 解析 CSS (生成 CSSOM 树)。
  • 构建 渲染树 (Render Tree)。
  • 执行 布局 (Layout)绘制 (Paint)

2. JS 引擎线程 (如 V8引擎)

该线程负责执行 JavaScript 代码。它与 GUI 渲染线程是互斥的。

想象一下: 如果 GUI 渲染线程正在努力地根据当前的 DOM 结构绘制页面(比如计算元素位置、颜色等),而 JS 引擎线程同时也在修改这个 DOM 结构(比如添加、删除元素,改变样式),那么就会出现严重的冲突。引发大量的重排,甚至显示一个不可预测的界面。

3. 事件触发线程 (Event Trigger Thread)

这个线程负责监听用户交互事件(如点击、鼠标移动)和系统事件。当事件发生时,它会将对应的回调函数推入到事件循环的宏任务队列中。

4. 定时器触发线程 (Timer Thread)

这个线程专门处理 setTimeoutsetInterval。浏览器会为定时器启动一个单独的线程,当设定的时间到达时,该线程会将对应的回调函数添加到宏任务队列中,等待 JS 引擎线程执行。

为什么 setTimeout 不准确?

setTimeout 回调函数并非严格按照设定时间执行,因为回调函数需要等待 JS 引擎线程空闲才能运行。即使时间到了,如果主线程正在忙于执行其他任务,回调函数也必须排队等待。

5. 异步 HTTP 请求线程 (Async HTTP Request Thread)

该线程负责处理网络请求,例如 fetchXMLHttpRequest (XHR)。当请求完成(成功或失败)时,它会将对应的回调函数推入到事件循环的队列中(通常是宏任务)。


D644F8F2-D8FC-474A-97AB-540EC884EA99.png