前端应该知道的浏览器知识

浏览器整体架构:多进程多线程

现代浏览器(以Chrome为代表)采用分层、多进程的架构,主要目的是安全、稳定和性能。一个典型的浏览器可以被抽象为下图所示的三层结构:

  • 第一层:用户界面 :我们看到的地址栏、书签栏、按钮等。它运行在独立的 浏览器进程 中,响应用户的全局操作。
  • 第二层:浏览器内核 :浏览器的"大脑",负责调度和管理。网络线程 处理请求,UI后端线程 绘制基础控件,而最核心的渲染引擎 (如Blink)和JS引擎 (如V8)则运行在独立的渲染进程中。
  • 第三层:数据持久层:负责Cookie、本地存储、缓存等数据的读写。

主要进程及其职责包括:

进程 职责
浏览器进程 负责界面显示(地址栏、书签)、用户交互、子进程管理等。
GPU进程 负责独立的图形绘制(3D CSS、WebGL)。
网络进程 负责所有网络资源加载。
渲染进程(核心) 每个标签页通常对应一个独立的渲染进程,负责解析HTML/CSS、执行JavaScript、进行布局和绘制(排版、渲染)。我们说的"主线程"就在这里。
插件进程 每个插件独立进程,防止崩溃影响浏览器。

所以,浏览器整体是多进程的。而在一个渲染进程内部,又包含多个线程协同工作

🧵 渲染进程内的线程分工

一个典型的渲染进程包含以下关键线程:

  1. GUI渲染线程 :负责解析HTML/CSS、构建DOM树、CSSOM树、布局和绘制等。注意:GUI渲染线程与JS引擎线程是互斥的
  2. JavaScript引擎线程(这就是我们常说的"主线程"或"UI线程") :负责执行JavaScript代码(如V8引擎)。我们常说的"JavaScript是单线程的",指的就是这个线程。
  3. 定时器触发线程 :管理setTimeoutsetInterval的计时,计时完毕将回调加入任务队列。
  4. 异步HTTP请求线程 :处理XMLHttpRequestfetch等网络请求,完成后将回调加入任务队列。
  5. 事件触发线程:管理事件循环,当事件(如点击)触发时,将对应的回调函数加入任务队列。
  6. 合成线程:将页面分层信息发送给GPU进程。

核心:"主线程"是什么?

我们通常所说的 "主线程" ,狭义上指 "JavaScript引擎线程" ,广义上指的是承担了JavaScript执行、页面渲染(GUI)、事件处理等核心工作的这个单一线程执行模型

因为GUI渲染线程JS引擎线程是互斥的,它们不能同时执行,所以可以理解为一个"工作主线程"在不同时段切换着做这两件事。其工作流程可以总结为下图:

为什么这样设计? 主要是为了保证DOM操作结果的一致性。如果JS线程和渲染线程同时工作,JS可能在渲染中途修改DOM,导致渲染出错。互斥执行简化了并发控制,但带来了性能挑战。

🧵 微观机制:渲染进程与事件循环

作为前端开发者,我们必须深入理解渲染进程的内部,因为我们的代码就在这里执行。下图描绘了渲染进程中,从接收网络数据到最终屏幕像素的关键工作流:

结合上图,我们来理解几个最关键的概念:

  1. 渲染流水线

    这是浏览器将代码变成像素的过程。你需要理解几个关键步骤:

    • 解析与构建树 :HTML解析为DOM树 ,CSS解析为CSSOM树
    • 布局:计算每个DOM元素在视口中的精确位置和大小(又称"回流")。
    • 绘制 :将元素的文本、颜色、边框等视觉信息填充到多个图层上(又称"重绘")。
    • 合成 :这是现代浏览器保持流畅的关键。合成线程 将各个图层分块,交由GPU进程 进行光栅化(变成位图),最后像叠盘子一样合成为最终画面。这个过程完全在独立的线程进行,不阻塞主线程
  2. 事件循环:JavaScript的并发模型

    是 JavaScript 实现异步编程的核心机制,其作用是协调同步任务异步任务的执行顺序,让单线程的 JS 能够高效处理非阻塞操作(如网络请求、定时器、DOM 事件)。

    • 宏任务队列 :包含 setTimeoutsetIntervalI/O、UI渲染、MessageChannel 等回调。

    • 微任务队列 :包含 Promise.thenMutationObserverqueueMicrotask 等回调。
      运行规则 :每执行一个 宏任务后,会清空整个微任务队列,然后检查是否需要渲染,接着再取下一个宏任务。

    核心规则一个宏任务 → 所有微任务 → (可能渲染)→ 下一个宏任务

💡 对前端开发的深刻启示

  1. 性能瓶颈在主线程 :所有同步JS、DOM操作、样式计算、布局都发生在同一个主线程上。这就是为什么长时间的同步JS会"卡死"页面------它阻塞了渲染和事件处理。

  2. 理解渲染时机 :浏览器会智能地合并多次DOM操作,但直接读取某些布局属性(如 offsetTopgetComputedStyle)会强制触发同步布局,导致性能骤降。

  3. 善用异步与分层

    • requestAnimationFrame 执行动画,让它与渲染周期对齐。
    • 将耗时计算移入 Web Worker(运行在独立线程,无法访问DOM)。
    • 利用CSS transformopacity 属性进行动画,它们可以由合成线程单独处理,完全避开主线程和重绘,效率最高。
  4. React调度器的用武之地 :React正是深刻理解了上述机制,才用 MessageChannel 将渲染工作拆分为5ms左右的可中断任务单元。每个单元执行后,通过事件循环将控制权交还浏览器,从而避免长任务阻塞,实现流畅的并发更新。

相关推荐
他是龙5512 小时前
第29天:安全开发-JS应用&DOM树&加密编码库&断点调试&逆向分析&元素属性操作
开发语言·javascript·安全
狗哥哥2 小时前
前端基础数据中心:从混乱到统一的架构演进
前端·vue.js·架构
树深遇鹿2 小时前
数据字典技术方案实战
前端·javascript·架构
爱吃大芒果2 小时前
Flutter 基础组件详解:Text、Image、Button 使用技巧
开发语言·javascript·flutter·华为·ecmascript·harmonyos
大布布将军2 小时前
一种名为“Webpack 配置工程师”的已故职业—— Vite 与“零配置”的快乐
前端·javascript·学习·程序人生·webpack·前端框架·学习方法
JosieBook2 小时前
【Vue】02 Vue技术——搭建 Vue 开发框架:在VS Code中创建一个Vue项目
前端·javascript·vue.js
科普瑞传感仪器2 小时前
航空航天制造升级:机器人高精度力控打磨如何赋能复合材料加工?
java·前端·人工智能·机器人·无人机·制造
前端开发呀2 小时前
成为开源项目的Contributor:从给uView-pro 贡献一次PR开始
前端·微信小程序
1024肥宅2 小时前
JavaScript 数组原生方法手写实现
前端·javascript·ecmascript 6