当前位置: 首页 > news >正文

详细解释浏览器是如何渲染页面的?

渲染流程概述

渲染的目标:将HTML文本转化为可以看到的像素点

当浏览器的网络线程收到 HTML 文档后,会产生一个渲染任务,并将其传递给渲染主线程的消息队列。在事件循环机制的作用下,渲染主线程取出消息队列中的渲染任务,开启渲染流程。

渲染流程概述

渲染流程的阶段(8个步骤):

在这里插入图片描述

  • HTML 解析
  • 样式计算
  • 布局
  • 分层
  • 绘制
  • 分块
  • 光栅化

每个阶段的输出将成为下一个阶段的输入,整个流程形成了一套高效的生产流水线。

1. 解析 HTML

第一步: 解析 HTML

在这里插入图片描述

  • HTML 解析: 浏览器会解析 HTML 文件,遇到 CSS 会解析 CSS,遇到 JS 会执行 JS
  • 外部资源的加载: 浏览器会启动一个预解析线程,提前下载外部的 CSSJS 文件。

关键点:

  • link 标签会在主线程解析到时,继续解析 HTML,不会阻塞。
    在这里插入图片描述
  • script 标签会暂停 HTML 解析,等待 JavaScript 下载并执行完成后,才能继续解析。
    HTML解析

解析完成后,浏览器得到 DOM 树CSSOM 树

2. 样式计算

第二步: 样式计算

主线程会遍历 DOM 树,计算每个节点的最终样式,称之为 Computed Style

这一过程存在转换操作,预设值(例如 red)转换成绝对值(例如 rgb(255, 0, 0)),单位(例如 em)转化为 px

此步骤后,我们得到了一棵包含样式的 DOM 树。

样式计算


3. 布局

第三步: 布局

布局阶段,浏览器会根据 DOM 树计算出每个节点的几何信息,如宽高、位置等。

布局树的特性(DOM树和Layout树不一定是一一对应的):

  • display: none 的节点不会出现在布局树中。
  • 伪元素 ::before 会出现在布局树中,尽管 DOM 树中没有。

完成布局后,浏览器会生成 布局树

布局


4. 分层

第四步: 分层

主线程会根据布局树,按照一套复杂的策略进行分层。

为什么要分层:

如果某一层发生变化,后续只处理这一层,从而提升性能。

影响分层的因素包括:滚动条、transformopacity 等,也可以通过will-change属性更大程度的影响分层结果。

分层


5. 绘制

第五步: 绘制

每一层的绘制指令集会被生成,用于描述图层如何呈现内容。

绘制

完成绘制后,主线程将绘制信息提交给 合成线程,剩下的工作由合成线程完成。

分块

6. 分块

第六步: 分块
在这里插入图片描述

合成线程将每一层分成多个小块,划分为更小的区域。

在这里插入图片描述

这一步会从线程池中取出多个线程来完成分块的工作。

7. 光栅化

第七步: 光栅化

合成线程将分块信息交给 GPU 进程,通过多个线程快速处理,优先处理靠近视口的区域。光栅化后的结果是每个块的位图。

光栅化
光栅化的过程中会启动GPU进程进行加速。
在这里插入图片描述

8. 画

最后一步:

合成线程生成 指引(quad)信息,描述每个位图如何绘制到屏幕的正确位置,并考虑旋转、缩放等变形。

变形发生在合成线程,与渲染主线程无关,正是因为如此,transform 样式非常高效。

最终,合成线程将指引信息提交给 GPU 进程,通过 GPU 硬件渲染生成屏幕上的图像。

画

总结

通过并行处理,浏览器能够在多个线程中同时完成渲染任务,保证页面能够快速响应用户交互,提高了整体性能。渲染流程的各个阶段和线程池的协作使得浏览器能够高效地绘制出用户所看到的页面,优化了体验和性能。

加速技巧:

  • will-change 属性可以提前告知浏览器需要优化的渲染层。
  • 使用 transformopacity 来避免页面重排,提高渲染效率。

相关文章:

  • 国网B接口协议图像数据上报通知接口流程详解以及上报失败原因(电网B接口)
  • Docker 网络详解:从 docker0 网桥到网络命名空间
  • 深入Docker核心技术:从Namespace到容器逃逸防御
  • OpenCV 04.19 练习
  • Python带有else子句的循环语句
  • 【漫话机器学习系列】210.标准化(Standardization)
  • docker 大模型
  • Cribl 优化EC2 ip-host-region 数据
  • Grouped Query Attention (GQA) PyTorch实现
  • 关于学习STM32的C语言的知识
  • matlab 处理海洋数据并画图的工具包--ocean_data_tools
  • 基于模板匹配的信用卡号码识别系统
  • 学习笔记十七——Rust 支持面向对象编程吗?
  • system V消息队列和信号量的学习
  • Python番外——常用的包功能讲解和分类组合
  • 服务治理-搭建Nacos注册中心
  • @EnableAsync+@Async源码学习笔记之六
  • 【自动化测试框架】什么是对象层?
  • [密码学基础]密码学常用名词深度解析:从基础概念到实战应用
  • npm 常用操作和配置
  • 被指违反代理协议遭南航暂停售票资格, 去哪儿网:今起恢复
  • 全球南方声势卓然壮大的历史逻辑——写在万隆会议召开70周年之际
  • 两大跨国巨头称霸GLP-1市场,国产减肥药的机会在哪?
  • 礼来公布口服降糖药积极结果,或年底前提交用于体重管理上市申请
  • 巡视杭州市工作动员会召开,市长姚高员表态
  • 接下来上海很热闹,天后天团轮番来开演唱会