跳到主要内容

浏览器原理✅

浏览器架构及主要组成部分?

答案

参考 浏览器的工作方式

浏览器核心组成部件如下图

  1. 界面:包括地址栏、后退/前进按钮、书签菜单等。浏览器界面的每个部分,但显示请求网页的窗口除外。
  2. 浏览器引擎:在界面和渲染引擎之间协调操作。
  3. 渲染引擎:负责显示请求的内容。例如,如果请求的内容是 HTML,则呈现引擎会解析 HTML 和 CSS,并在屏幕上显示解析的内容。
  4. 网络:对于 HTTP 请求等网络调用,在平台无关接口后面为不同平台使用不同的实现。
  5. 界面后端:用于绘制组合框和窗口等基本 widget。此后端公开的接口并非平台专用。在底层,它使用操作系统界面方法。
  6. JavaScript 解释器:用于解析和执行 JavaScript 代码。
  7. 数据存储:这是持久层。浏览器可能需要在本地保存各种数据,例如 Cookie。浏览器还支持 localStorage、IndexedDB、WebSQL 和 FileSystem 等存储机制。 浏览器的主要组成部分是什么

整个进程模型参考 https://www.chromium.org/developers/design-documents/multi-process-architecture/

  • Borwser Process 主进程 管理渲染进程和其他进程
    • Main Thread 主线程,管理渲染进程
    • IO Thread IO线程,处理网络请求
  • Renderer Process 渲染进程,负责渲染页面
    • Main Thread 渲染进程的主线程,负责解析HTML、CSS和JavaScript
    • Render Thread 工作线程,处理后台任务等
提示

这是一个概念上的示意图,实际上 chrome 还包含插件进程、GPU 进程等其他进程,此外也可通过配置等控制进程执行模式。

延伸阅读

常见浏览器内核及区别?

答案
内核概述
Blink由Google和Opera Software共同开发,基于WebKit内核,是Chrome浏览器和Opera浏览器的渲染引擎。
WebKit由苹果公司开发,为Safari浏览器所用。Kit内核在HTML、CSS和JavaScript处理方面都表现出色,支持的CSS特性较多。
Gecko由Mozilla开发,主要用于Firefox浏览器。
Trident由Microsoft开发,主要用于Internet Explorer浏览器,也是Windows系统自带的默认浏览器内核。从 2018 微软切换到基于 chromium 的 Blink 内核的 Edge 浏览器后,Trident 内核逐渐被淘汰。

输入 url 到页面渲染全过程?

答案
  1. Loading(加载阶段)
    1. URL 解析 , 浏览器解析 URL,提取协议、域名、路径等信息。
    2. Cache Check ,检查缓存,判断资源是否新鲜,决定是否重新请求。
    3. DNS, 进行 DNS 查询,解析出服务器 IP 地址。
    4. TCP, 建立 TCP 连接(三次握手)。
    5. TLS, 如果是 HTTPS 协议,进行 TLS 握手,建立安全连接。
    6. HTTP, 发送 HTTP 请求,获取资源。
  2. Parsing(HTML 和资源解析)
    1. DOM Tree 解析 HTML 文档,构建 DOM 树。注意 DOM 树的解析是流式的,浏览器会在解析过程中逐步构建 DOM 树,而不是等到整个文档加载完成再解析
    2. JS Execution 解析并执行 JavaScript,可能会修改 DOM 树或触发其他资源加载。
    3. CSSOM Tree 解析 CSS,构建 CSSOM 树
  3. Style(样式计算)

    详见 style

    1. CSSOM 将样式表解析为 CSSOM(CSS 对象模型)。
    2. RenderObject Tree 基于 DOM 节点和 CSSOM 构建渲染对象树。
  4. Layout(布局计算)

    详见 layout

    1. RenderLayer Tree 依据 RenderObject 和层叠上下文生成 RenderLayer 树。
    2. Layout 计算每个渲染对象的实际位置与尺寸。
  5. Paint(绘制阶段)

    将样式化的内容转化为图层绘制命令与位图,完成从逻辑表示到图像数据的过渡。

    1. GraphicsLayer Tree 根据是否具有合成需求(如 transformopacitywill-change 等)从 RenderLayer 构建 GraphicsLayer Tree,每个 GraphicsLayer 可单独绘制和合成。
    2. Paint Setup 为每个图层生成绘制命令(Display List,如 SkPicture),这些命令是可复用的中间格式。
    3. Rasterization 将绘制命令发送至 GPU 或 Raster 线程栅格化为位图,可存储于内存或 GPU 纹理中,等待合成。
  6. Compositing(合成阶段)

    将所有图层位图合成为最终帧并显示。详见 Compositing

    1. Layer Compositing Compositor 线程根据 GraphicsLayer Tree 的结构,决定图层叠加顺序、混合与裁剪,并通过 GPU 将各图层位图合成为完整画面。
    2. Presentation 合成帧经由 GPU 管线提交至操作系统显示系统(如 Windows DWM 或 macOS Quartz),完成屏幕更新。
  7. Display(显示阶段)

    将合成的图像数据发送到显示设备(如屏幕、投影仪等),完成最终的视觉呈现。

    1. Display Output GPU 负责将合成的图像数据发送到显示设备进行渲染

关键流程参考 了解关键路径 如下图

延伸阅读

DOM/CSSOM/渲染树构建?

答案

核心概念

DOM(文档对象模型)和 CSSOM(CSS对象模型)是浏览器渲染页面的基础数据结构。浏览器会将 HTML 解析为 DOM 树,将 CSS 解析为 CSSOM 树,然后结合两者生成渲染树(Render Tree),用于后续的布局和绘制。

提示

详细解释

  • 解析 HTML 生成 DOM 树:浏览器自上而下读取 HTML,遇到标签就创建节点,嵌套结构形成父子关系,属性和文本也会作为节点挂载。
  • 解析 CSS 生成 CSSOM 树:CSS 解析器将样式表转为规则对象,形成树状结构,便于后续样式计算。
  • 构建渲染树:DOM 树与 CSSOM 树结合,过滤掉 display: none 的节点,仅保留可见元素,生成渲染树。每个渲染树节点都包含 DOM 元素及其最终计算样式。
  • 渲染树用于布局(Layout)和绘制(Paint)阶段,决定元素的几何信息和视觉表现。

CSS选择器从右往左解析原理

浏览器在匹配 CSS 选择器时,从选择器最右侧(即目标元素)开始,逐级向左查找父节点是否匹配,直到根节点或选择器左端。这样可以快速排除不匹配的分支,提升性能。例如 .a .b .c,会先查找 .c,再判断其父节点是否有 .b,依次类推。

代码示例

<div class="a">
<div class="b">
<span class="c">text</span>
</div>
</div>
.a .b .c { color: red; }

浏览器会先定位 .c,再判断其父级是否有 .b,再向上查找 .a,而不是从 .a 开始遍历所有后代。

常见误区与开发建议

  • 误区:以为 CSS 选择器是从左往右解析,导致过度嵌套选择器以期望优化性能,实则适得其反。
  • 建议:减少层级选择器和通配符(*)的使用,优先使用类选择器,提升样式匹配效率。
提示

合理优化选择器结构,能显著提升页面渲染性能,尤其在大型 DOM 树下效果明显。

延伸阅读

事件循环原理、宏任务与微任务?

答案

浏览器事件循环详见 HTML 规范 event loops 章节, 基于规范定义的 事件循环处理模型

  1. 宏任务本质就是 task
    • 例如:setTimeoutsetIntervalI/O 操作UI 事件等。会按照顺序放入任务队列中。执行存在优先级
  2. 微任务本质就是 microtask
    • 例如:Promise.thenMutationObserver等。
    • 必须在一个宏任务执行完毕后,检查微任务队列是否有任务,如果有,则执行所有微任务,直到微任务队列清空。
  3. 此外对于 setTimeoutsetInterval 的任务,在浏览器处于后台模式超过 5 分钟的时候默认会触发 throttle 逻辑,会被延缓到 1 分钟触发一次,具体的不同事件类型限制情况详见 task type
提示

chromium 的任务类型,详见 task_typs 文件, event_loop 说明详见 event_loop

延伸阅读

重排和和重绘及优化?

答案
  1. 重排(reflow) 发生在浏览器重新计算网页的某些部分的位置和几何形状时(例如在交互式站点更新后)。这通常会紧接着重绘(repaint),即浏览器重新绘制网页以显示更新后的视觉效果。
  2. 重绘(repaint) 重绘在浏览器重新绘制网页以显示由 UI 更改引起的视觉更新时发生,例如在交互式站点上进行更新后。这通常是在重排之后发生的,重排是浏览器重新计算网页的某些部分的位置和几何形状。

重排和重绘是导致浏览器性能下降的主要原因之一,这里重点关注重排,因为它比重绘更耗费资源。

参考 What forces layout / reflow 常见触发重排的操作如下

  • 直接修改元素的几何属性,如 widthheighttopleftmarginpaddingborder-width 等。
  • 插入、删除 DOM 节点,或更改节点结构(如 appendChildremoveChildinsertBefore 等)。
  • 读取会触发布局的属性和方法,如 offsetWidthoffsetHeightoffsetTopoffsetLeftclientWidthclientHeightgetBoundingClientRect()getClientRects()
  • 访问滚动相关属性和方法,如 scrollTopscrollLeftscrollWidthscrollHeightscrollTo()scrollBy()scrollIntoView()
  • 设置或获取元素的 focus()select()innerText
  • 读取 window.getComputedStyle(),尤其是访问返回对象的属性时。
  • 修改表单元素的选区(如 input.select()textarea.select())。
  • 读取或设置 SVG 某些属性和方法(如 getBBox()getComputedTextLength())。
  • Canvas2D API 某些操作(如 fillText()strokeText()、设置 directionfilter)。
  • 读取窗口尺寸相关属性,如 window.innerWidthwindow.innerHeightwindow.scrollXwindow.scrollY(部分浏览器实现)。

在错误的触发重排的场景下,通过如下方式优化性能

  1. 批量修改 DOM:将多次 DOM 操作合并为一次操作,减少重排次数。例如,使用 DocumentFragmentcloneNode 批量插入节点。
  2. 使用 CSS 类:通过添加或删除 CSS 类来批量修改样式,而不是逐个修改样式属性。这样可以减少重排次数。
  3. 使用 requestAnimationFrame:将需要重排的操作放在 requestAnimationFrame 回调中执行,这样可以确保在浏览器下一次重绘之前进行布局计算。
  4. 避免频繁读取布局属性:如果需要多次读取布局属性,可以先将其存储在变量中,避免多次触发重排。例如,使用 let rect = element.getBoundingClientRect() 存储布局信息,然后在需要时使用该变量。
  5. 使用 will-change:对于需要频繁更新的元素,可以使用 will-change CSS 属性来提示浏览器提前进行优化,减少重排的开销。
  6. 使用 CSS 动画:尽量使用 CSS 动画而不是 JavaScript 动画,CSS 动画通常会触发 GPU 加速,减少重排的开销。

对于 css 详见 CSSTriggers 讲解哪些 CSS 属性会触发重排和重绘。

延伸阅读

浏览器缓存中 Memory Cache 和 Disk Cache, 有啥区别?

答案
  • Memory Cache(内存缓存):资源直接存储在内存中,访问速度极快(纳秒级),但容量有限,通常在刷新或关闭页面后失效。适合当前会话内频繁访问的资源。
  • Disk Cache(磁盘缓存):资源存储在硬盘上,访问速度比内存慢(毫秒级),但容量大,关闭浏览器后依然保留。适合长期存储和较大体积的资源。

核心概念

Memory Cache(内存缓存)和 Disk Cache(磁盘缓存)都是浏览器用来提升资源加载速度的缓存机制,区别在于存储介质和访问速度。

详细解释

  • Memory Cache:资源被直接缓存在内存中,访问速度极快(纳秒级),但容量有限,重启浏览器或刷新页面后通常会失效。适合短期、频繁访问的资源。
  • Disk Cache:资源被缓存在本地硬盘,访问速度比内存慢(毫秒级),但容量大,关闭浏览器后依然保留。适合长期存储、较大体积的资源。

详情参考讨论 浏览器是根据什么决定「from disk cache」与「from memory cache」?

48%