浏览器的工作原理
多进程架构
现代浏览器采用 多进程 架构以提高安全性、稳定性和性能。多进程架构将页面隔离,避免单个页面崩溃拖垮整个浏览器。渲染进程运行在受限的沙箱中,即便执行恶意脚本也不会直接危及操作系统安全。
浏览器进程
负责 UI 渲染、用户交互、标签页管理、网络进程的调度等,它是整个浏览器的大脑。
渲染进程
每个页面通常在独立的渲染进程中运行。渲染进程内部包含 HTML/CSS 解析、V8 JavaScript 引擎、布局引擎、图层管理等组件,用于将网页内容呈现为像素。
网络进程
统一处理所有网络请求(HTTP/2、HTTP/3、TLS 等),下载资源后分发给渲染进程。网络进程在请求 CSS/JS 时会根据媒体查询判断是否阻塞渲染。
GPU 进程
负责图层的栅格化和合成,加速动画和 3D 渲染。
插件或扩展进程
封装第三方插件或扩展,出现崩溃不会影响浏览器其他部分。
渲染流水线
资源获取
- 处理地址栏/点击/重定向,可能经过 Service Worker。
- 网络进程负责 DNS、TLS、HTTP/2/3 连接复用与首包返回,并根据响应头推断可预加载/预连接资源。
- 把高延迟的 I/O 与主线程隔离,利用连接池和多路复用降低首字节等待。
- 更快的 TTFB/TTI,失败隔离(网络进程崩溃不拖垮渲染)。
合理使用
preconnect/dns-prefetch/preload,用 SW 做缓存回源与离线兜底。
HTML解析
- 渲染进程中的 HTML 解析器边收边解字节流,并构建 DOM。
- 解析过程中遇到 CSS,浏览器会启动⼀个预解析器率先下载和解析 CSS。
- 解析过程中遇到 JS 代码,则必须暂停⼀切⾏为,等待下载执⾏完后才能继续,预解析线程可以分担⼀点下载 JS 的任务。
同步
<script>会阻塞解析,defer在 DOM Ready 后执行,async一到就执行。
样式计算
- DOM × CSSOM → 计算样式(Recalc Style),剔除
display:none节点,得到渲染树(Render/Frame Tree)。 - 把语义树(DOM)与样式规则转为可布局的盒模型视图;仅可见元素进入后续管线。
- 减少无用节点参与后续昂贵阶段(布局/绘制)。
content-visibility:auto;/contain把子树与外界隔离,降低样式与布局影响域。
布局
- 为渲染树中的每个盒子计算几何信息(位置、尺寸、换行、分页/分栏、表格排版等)。
- 遇到
position: fixed/absolute、多列与复杂inline排版会增加复杂度。 - 像排版引擎一样给每个盒子定位,保障视觉与交互正确。
- 得到可用于绘制的布局树与几何缓存,后续绘制可复用。
新增/删除节点、修改盒子尺寸/字体、读取布局信息(在有未结算写入时)、窗口 resize、滚动(特定情况下)。
分层
- 创建图层树(独立合成层:新层叠上下文、变换/滤镜、
video/canvas、will-change等). - 生成绘制列表(背景、边框、文本、阴影、图片等)。
- 把可复用/可独立合成的区域拆分到独立层,降低重绘与滚动成本。
- 滚动与
transform/opacity动画可脱离主线程,仅在合成器中更新。
少量使用
will-change/transform: translateZ(0)以“合成器驱动”动画,过多会吃内存。
绘制
为每⼀层⽣成如何绘制的指令,渲染主线程的⼯作到此为⽌,剩余步骤交给其他线程完成。
分块
分块会将每⼀层分为多个⼩的区域,此过程会交给多个线程同时进⾏。
光栅化
- 光栅化是将每个块变成位图,优先处理靠近视⼝的块。
- 此过程会⽤到 GPU 加速。
合成
- 合成线程计算出每个位图在屏幕上的位置,交给 GPU 进⾏最终呈现。
- 合成线程根据输入事件/滚动/动画对各瓦片做矩阵变换并合成一帧提交给 GPU。
- 并行化重度工作,把每帧的变换留给轻量的合成器完成。
- 高帧率滚动与动画;减少因主线程繁忙导致的掉帧。
回流
当需要重新计算盒子几何信息时触发的布局阶段(如内容变化、样式影响尺寸、读取布局信息导致同步刷新),都会发生回流现象。
重绘
样式改变但不影响几何信息(如 color、background、box-shadow)时,跳过布局、重新绘制位图。重绘仅影响命中的绘制列表范围,成本低于回流。
独立合成层
合理地使用独立合成层,可减少回流与重绘。
常见误区
- 读写交错:先写样式后立刻读
offsetHeight/scrollTop/getComputedStyle会触发强制同步布局;解决:把写合并、把读合并,或放到requestAnimationFrame。 - 大量DOM:大量节点让样式计算与布局指数级放大;使用
content-visibility:auto;、虚拟列表、分页加载。 - 不必要的图层:过多
will-change让 GPU 内存暴涨;应限量使用并在动画结束后移除。
性能优化
样式/布局层
- Containment:
contain: layout style paint;或content-visibility:auto;隔离子树影响域。 - 响应式策略:优先
@container与现代布局(Grid/Flex),减少 JS 测量。 - 避免抖动:首屏内联关键 CSS;字体使用
font-display: swap;图片提供尺寸/占位,降低 CLS。
动画/交互层
- 只合成的动画:优先
transform与opacity;必要时加will-change。 - 帧内时序:动画更新放
rAF;非紧急工作放requestIdleCallback或切 Worker。 - 输入响应:把重活分片(小任务 < 3~5ms),减少长任务。
JS/V8 层
- 避免主线程阻塞:大计算用 Web Worker/OffscreenCanvas。
- 减少同步布局读:读布局放一起,写样式放一起。
- 模块化与按需执行:
type=module的动态导入、路由级拆分;使用懒执行/延迟解析。
渲染/合成层
- 合理分层:对滚动容器/动画元素创建合成层;避免半透明大区域叠加。
- 图片/视频:使用现代格式(WebP/AVIF),合理
srcset/sizes,开启decoding=async与loading=lazy。