浏览器的工作原理是怎么样的?

浏览器进程

最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程,下面我们来逐个分析下这几个进程的功能。

  • 浏览器进程:负责管理和协调其他进程。它主要处理用户界面、标签页管理、窗口管理、地址栏、书签、导航、网络请求的调度、子进程管理,同时提供存储等功能。
  • 渲染进程: 核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  • GPU 进程:Chrome 使用 GPU 进程来加速图形的渲染。它处理 3D CSS、WebGL、视频解码、以及图形相关的硬件加速任务。
  • 网络进程:负责管理所有的网络请求和数据传输,包括 HTTP、HTTPS、WebSocket 等。这个进程负责处理网络资源加载和缓存管理
  • 插件进程:专门用于运行浏览器插件(例如 Flash)。每个插件可以在一个独立的进程中运行。
  • 扩展进程:Chrome 扩展(如广告拦截器、密码管理器)通常在单独的进程中运行。这些进程执行扩展的后台任务、内容脚本、以及与网页和浏览器之间的交互。
  • 实用程序进程:用于处理浏览器的其他任务,如音视频解码、PDF 渲染、文件类型解析等。这些任务被分配给独立的实用程序进程,以确保浏览器主进程的稳定性和性能。
  • 服务工作进程:处理与 Service Workers 相关的任务,包括缓存管理、消息推送、后台同步等功能。这些进程允许 Web 应用在用户不直接与页面交互时仍能执行后台任务。
  • 内存管理进程:监控和管理 Chrome 的内存使用情况。它有助于防止内存泄漏、优化内存分配,并在需要时触发垃圾回收。
  • 其他进程:Chrome 有时会启动其他专门的进程以处理特定任务或实验性功能。例如,实验性功能可能会在不同的进程中进行测试,以确保不会影响核心浏览器的稳定性。

浏览器的渲染流程

  1. 浏览器接收 HTML ,javascript和 CSS 代码

    当用户访问一个网页时,浏览器会通过网络请求获取 HTML、CSS 和 JavaScript 文件。这些文件通过网络协议(例如 HTTP/HTTPS)传输到浏览器。浏览器开始下载这些资源并开始解析。
  2. 构建 DOM 树 (Document Object Model)

    浏览器开始逐行解析 HTML 文件,生成一个内部的结构化树,称为 DOM 树。这棵树代表了 HTML 文档的结构,其中每个节点对应一个 HTML 元素(如 body、div、h1 等)
  3. 构建 CSSOM 树 (CSS Object Model)

    浏览器同时解析所有与页面关联的 CSS 文件,包括 style 标签内的样式和外部的样式表链接。
  4. 合并 DOM 和 CSSOM 树为渲染树 (Render Tree)

    浏览器将 DOM 树和 CSSOM 树合并,生成渲染树。渲染树只包含可见元素(例如,display: none 的元素不会在渲染树中)。
  5. 布局 (Layout)

    计算元素位置和大小:在这个阶段,浏览器根据渲染树来计算每个元素在屏幕上的确切位置和大小,这个过程也称为 回流(reflow) 或 布局(layout)。
  6. 分层 (Layering) 和 分块 (Tiling)
    • 分层:一些复杂的元素(如包含 3D 变换、动画、固定定位等)会被提升为单独的图层。这有助于提高渲染性能,因为它允许特定的图层单独重绘而不影响其他图层。
    • 分块:对于大的图层,浏览器会将其分成多个小块(tiles)。这使得在滚动或动画过程中,只需重绘特定的块,而不是整个图层。
  7. 绘制 (Painting)
    • 绘制指令生成:浏览器将渲染树节点转换为绘制指令,指令会详细描述应该如何绘制每个节点的内容,例如颜色、边框、文字等。
    • 逐层绘制:每个图层都按照从背景到前景的顺序进行绘制,这个过程生成了最终要呈现的图像。
  8. 合成 (Compositing)

    浏览器的合成器进程会将所有图层组合在一起,形成一个最终的图像输出。这一步可以在 GPU 中完成,以加速渲染过程
  9. 显示 (Display)

    合成后的图像最终通过显示器输出,呈现给用户。这个过程可能包含了多次更新以适应动态变化,如用户滚动、JavaScript 动画、用户交互等。
  10. 持续的渲染与更新

重排”“重绘”和“合成”

  • 重排:更新了元素的几何属性

    通过 JavaScript 或者 CSS 修改元素的几何位置属性,例如改变元素的宽度、高度等,那么浏览器会触发重新布局,解析之后的一系列子阶段,这个过程就叫重排。无疑,重排需要更新完整的渲染流水线,所以开销也是最大的
  • 重绘:更新元素的绘制属性

    如果修改了元素的背景颜色,那么布局阶段将不会被执行,因为并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段,这个过程就叫重绘。相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些。
  • 合成

    使用 CSS 的 transform 来实现动画效果,这可以避开重排和重绘阶段,直接在非主线程上执行合成动画操作。这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率。

    除此之外以下 CSS 属性通常不会触发重排和重绘,只会影响复合阶段(在 GPU 上操作),从而避免了性能开销:
    • transform:例如 transform: translateX(100px);
    • opacity:例如 opacity: 0.5;
    • filter:例如 filter: blur(5px);
    • will-change:例如 will-change: transform;(明确告诉浏览器即将变化的属性,可以优化复合性能)
    • backface-visibility:例如 backface-visibility: hidden;