浏览器的渲染原理

article/2025/7/6 13:14:23

浏览器的渲染原理

  • 掘金

整个过程

网络

  • 网络线程: 收到html,css,js 文件资源. 产生一个渲染任务,并将其传递给渲染主线程的消息队列.

渲染

  • 在事件循环机制下, 渲染主线程取出消息队列中的渲染任务,开启渲染流程.
    在这里插入图片描述

整个过程

  • 渲染主线程 完成 绘制之前的所有工作
  • 合成线程和GPU 完成后续工作

第一步:解析HTML

1.1. 解析HTML字符串 => 生成 DOM 树 在控制台 直接打印 console.dir(document) 查看

// 等效于以下代码 这里就不会再发送网络请求了

function removeTag(htmlStr) {const parser = new DOMParser(); // 等效于const doc = parser.parseFromString(htmlStr, 'text/html');return doc;
}
1.2. 解析CSS字符串 => 生成 CSSOM树 (CSS object model)
  • CSS解析不会阻塞HTML解析 :为了提高解析效率,浏览器会启动一个预解析线程 率先下载和解析 CSS
  • 浏览器默认样式表: user agent stylesheet
    在这里插入图片描述
  • 控制台打印 CSSOM树(除了浏览器默认样式表的数据不能修改,其他都能修改)
    在这里插入图片描述
  • 包含1.浏览器默认样式, 2.内部样式,3.外部样式,4.行内样式
1.3 解析遇到JS则立即执行JS
  • 渲染主线程遇到JS时 必须暂停一切行为,等待下载执行完成后才能继续预解析线程可以分担一点下载 JS 的任务. 这是因为JS的代码可能会修改当前的DOM树,所以DOM树的生成必须暂停.

第二步: 样式计算 - Recalculate Style

  • 将第一步获得的 CSS树 和 DOM树 进行样式计算, 生成计算后的样式 = 最终样式 = 所有的CSS属性全部有值
    在这里插入图片描述
  • 在这个过程中,很多预设值会变成绝对值, 比如 red 会变成 rgb(255,0,0); 相对单位会变成绝对单位, 比如 em 会变成 px 最终得到一颗带有样式的 DOM 树
  • 控制台查看计算后的样式
    在这里插入图片描述

第三步: 布局 - Layout

  • 布局阶段会依次遍历 DOM 树的每一个节点,计算每个节点的几何信息.例如节点的宽高,相对包含块的位置.
  • 布局树 不一定和 DOM 树 一一对应 ,伪元素会在布局树, 但不在 DOM 树中, display: none 的 节点没有任何几何信息因此不在布局树中. 还有 匿名行盒,匿名块盒等等都会导致DOM树和布局树无法一一对应.

第四步: 分层 - Layer

在这里插入图片描述
在这里插入图片描述

  • 滚动条单独分层

第五步: 绘制 - Paint

  • 为每一层生成如何绘制的指令
  • 类似于canvas
  • 渲染主线程的工作到此为止,剩余步骤交给其他线程完成

第六步: 分块 - Tiling

  • 分块会将每一层分为多个小的区域
  • 这一步是 合成线程 完成.
  • 合成线程首先对每个图层进行分块,将其划分为更多的小区域…
  • 它会从线程池中拿取多个线程来完成分块工作.

第七步: 光栅化 - Raster

  • 光栅化是将每个块变成位图
  • 优先处理靠近视口的块
  • 此过程会用到 GPU 加速(GPU 进程)

第八步: 画 - Draw

  • 合成线程计算出每个位图在屏幕上的位置, 交给GPU 进行最终呈现

常见面试题

  • 什么是 reflow(重排)?
    • reflow 的本质就是重新计算 layout 树。
    • 当进行了会影响布局树的操作后,需要重新计算布局树,会引发 layout。
    • 为了避免连续的多次操作导致布局树反复计算,浏览器会合并这些操作,当 JS 代码全部完成后再进行统一计算。所以,改动属性造成的 reflow 是异步完成的。
    • 也同样因为如此,当 JS 获取布局属性时,就可能造成无法获取到最新的布局信息。
    • 浏览器在反复权衡下,最终决定读取属性立即 reflow。
  • 什么是 repaint(重绘)?
    • repaint 的本质就是重新根据分层信息计算了绘制指令。
    • 当改动了可见样式后,就需要重新计算,会引发 repaint。
    • 由于元素的布局信息也属于可见样式,所以 reflow 一定会引起 repaint。
  • 为什么 transform 的效率高?
    • 因为 transform 既不会影响布局也不会影响绘制指令,它影响的只是渲染流程的最后一个draw阶段
    • 由于 draw 阶段在合成线程中,所以 transform 的变化几乎不会影响渲染主线程。反之,渲染主线程无论如何忙碌,也不会影响 transform 的变化。
      在这里插入图片描述

http://www.hkcw.cn/article/NNXGkDemns.shtml

相关文章

【30万像素实时调控!石墨烯“魔镜”突破毫米波极限】

12厘米见方的超表面,藏着30万个比头发丝还细的像素单元,正在无声地操控着无形的太赫兹波束。曼彻斯特大学的科学家们将石墨烯的非凡电学特性与现代显示技术巧妙融合,创造出世界上最大规模的可编程智能超表面。想象一下,只需轻轻点…

线性调频波形测距测速信号处理——全代码+注释

clear all close all clc %% 参数设置 fs600e6;%采样率 fc10.45e9;% 波形发射载频 t10e-6;%脉宽 f050e6;%波形中频频率 B10e6;%带宽 uB/(2*t);%调频斜率 Tv100e-6;% 脉冲重复周期 Num64;% 测速脉冲数 lamdfs/B;% 抽取带宽 Nsround(fs*t); NTvround(fs*Tv); tt0:1/fs:t-1/fs; ff…

Spine工具入门教程2之导入

1、导入定义 从原画转化为Spine的环节。 (1)选择路径,拖动图片导入方式 缺点:定位不准 【使用批量导出的方式】 在PS工具中,选择所有图层后右键选择导出。 在Spine工具中,选择路径导入图片。 然后再拖…

吴恩达MCP课程(1):chat_bot

原课程代码是用Anthropic写的,下面代码是用OpenAI改写的,模型则用阿里巴巴的模型做测试 .env 文件为: OPENAI_API_KEYsk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx OPENAI_API_BASEhttps://dashscope.aliyuncs.com/compatible-mode…

Z-AnyLabeling1.0.1

1.前段时间写了第一个版本的Z-AnyLabeling,使用起来只能标注一个文件夹里面的图片,不能标注多个文件夹数据 2.现在更新一个版本可以标注多个文件夹数据,同时可以保存成一个工程文件。 3.软件开发环境:Pycharm,Pyside6 4.软件界面 …

告别充电焦虑:移动充电桩如何优化传统充电模式?

新能源汽车的普及,充电难、充电慢的问题日益凸显。传统固定充电桩受限于场地和电网,难以满足用户灵活、高效的充电需求。而移动充电桩的出现,正逐步改变这一局面。它以其灵活部署、智能调度和高效补能的优势,为缓解充电焦虑提供了…

github访问慢

解决github外玩访问慢 ,点击解决方案

榕壹云医疗服务系统:基于ThinkPHP+MySQL+UniApp的多门店医疗预约小程序解决方案

在数字化浪潮下,传统医疗服务行业正面临效率提升与客户体验优化的双重挑战。针对口腔、美容、诊所、中医馆、专科医院及康复护理等需要预约或诊断服务的行业,我们开发了一款基于ThinkPHP+MySQL+UniApp的多门店服务预约小程序——榕壹云医疗服务系统。该系统通过模块化设计与开…

RPA如何支持跨平台和跨浏览器的自动化

RPA,即机器人流程自动化(Robotic Process Automation),正日益成为企业实现业务流程高效自动化的关键技术。在复杂的数字化环境中,跨平台和跨浏览器的自动化需求极为迫切,RPA 通过多种技术手段和策略来满足这…

SpringBoot简单体验(TODO)

1 Helloworld 打开:https://start.spring.io/ 选择maven配置。增加SpringWeb的依赖。 Generate之后解压,代码大致如下: hpDESKTOP-430500P:~/springboot2/demo$ tree ├── HELP.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── s…

事件驱动架构入门

主要参考资料: 软件架构-事件驱动架构: https://blog.csdn.net/liuxinghao/article/details/113923639 目录 简介事件队列事件日志事件收集器响应队列读事件 vs. 写事件 简介 事件驱动架构是一种系统或组件之间通过发送事件和响应事件彼此交互的架构风格。当某个事…

2024全国青少年信息素养大赛python复赛真题——计算握手次数

2024全国青少年信息素养大赛python复赛真题——计算握手次数 题目可点下面去处,支持在线编程,在线测评~ 计算握手次数(2024全国青少年信息素养大赛复赛真题)_python_少儿编程题库学习中心-嗨信奥 题库收集了历届各白名…

[春秋云镜] CVE-2023-23752 writeup

首先奉上大佬的wp表示尊敬:(很详细)[ 漏洞复现篇 ] Joomla未授权访问Rest API漏洞(CVE-2023-23752)_joomla未授权访问漏洞(cve-2023-23752)-CSDN博客 知识点 Joomla版本为4.0.0 到 4.2.7 存在未授权访问漏洞 Joomla是一套全球知名的内容管理…

Trae Builder编程助手-基于Builder完成算法生成+api接口实现全流程

Trae插件下载链接 ​ 总结 使用过Builder后,我的感觉就是,可以通过嘴写代码!!雄起吧,我们程序员的口语交际能力。同时重点要先把自己的编码环境设置好,否则很麻烦 参考 安装过程单击Trae插件下载链接&…

python笔面试题汇总

1. 如何利用SciKit包训练一个简单的线性回归模型 利用linear_model.LinearRegression()函数 # Create linear regression object regr linear_model.LinearRegression() # Train the model using the training sets regr.fit(data_X_train, data_y_train) 2. 例举几个常用的…

pandas数据分析

数据读取 import pandas as pd df pd.read_csv(D:\my_app\python\python project\data\sample_data.csv) print(df)数据保存 import pandas as pd# 创建示例数据 data {Name: [Alice, Bob, Charlie, David, Eve],Age: [25, 30, 35, 28, 22],City: [Beijing, Shanghai, Guan…

力扣每日一题——找到离给定两个节点最近的节点

目录 题目链接:2359. 找到离给定两个节点最近的节点 - 力扣(LeetCode) 题目描述 解法一:双指针路径交汇法​ 基本思路 关键步骤 为什么这样可行呢我请问了? 举个例子 特殊情况 Java写法: C写法&a…

一种通用图片红色印章去除的工具设计

朋友今天下午需要处理个事情,问我有没有什么好的办法能够去除,核心问题是要去除图片上的印章。记得以前处理过类似的需求,photoshop操作比较简单,本质是做运算。这种处理方式有很多,比如现在流行的大模型,一…

Bean对象循环依赖

Spring 循环依赖是指 多个 Bean 对象之间形成相互依赖的闭环。 三级缓存解决循环依赖 缓存级别存储内容作用一级缓存完整的 Bean(singletonObjects)存放已初始化完成的 Bean二级缓存半成品 Bean(earlySingletonObjects)存放已实例…

文心快码参编国内首个软件开发智能体技术规范

近期,中国信息通信研究院(简称“中国信通院”)与中国工商银行、北京兴云数科技术有限公司、北京百度网讯科技有限公司牵头,联合农业银行、邮储银行、科大讯飞、腾讯、阿里、华为等二十余家头部企业,共同编制并正式发布…