浏览器渲染原理(面试重点)
一、浏览器是如何渲染页面的
常见的简洁答案:
- 浏览器内核拿到内容后,渲染流程大致如下:
- 解析HTML,构建Dom树;
- 解析CSS,构建Render树;(将CSS代码解析成树形的数据结构,与Dom树结合形成Render树)
- 布局Render树(Layout/reflow),负责各元素尺寸、位置的计算;
- 绘制Render树(painting),绘制页面像素信息;
- 浏览器将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上
牛逼的震惊面试官的答案:
- 当浏览器的网络线程收到HTML文档后,会产生一个渲染任务,并将其传递给渲染主线程的消息队列。在事件循环机制的作用下,渲染主线程取出消息队列中的渲染任务,开启渲染流程。
- 整个渲染流程分为多个阶段,分别是:HTML解析、样式计算、布局、分层、绘制、分块、光栅化、画。每个阶段都有明确的输入和输出,上一个阶段的输出会成为下一个阶段的输入,这样整个渲染流程就形成了一套组织严密的生产流水线。
- 渲染的第一步是解析HTML:
- 解析过程中遇到CSS就解析CSS,遇到JS就解析JS。为了提高解析效率,浏览器在开始解析前,会启动一个预解析的线程,率先下载HTML中的外部CSS文件和外部的JS文件
- 如果主线程解析到link位置,此时外部的CSS文件还没有下载解析好,主线程不会等待,继续解析后续的HTML。这是因为下载和解析CSS的工作是在预解析线程中进行的。这就是CSS不会阻塞HTML解析的根本原因。
- 如果主线程解析到script位置,会停止解析HTML,转而等待JS文件下载好,并将全局代码解析执行完成后,才能继续解析HTML。这是因为JS代码执行的过程可能会修改当前的DOM树,所以DOM树的生成必须暂停。这就是JS会阻塞HTML解析的根本原因。
- 第一步完成后,会得到DOM树和CSSOM树,浏览器的默认样式、内部样式、外部样式、行内样式均会包含在CSSOM树中。
- 渲染的下一步是样式计算:
- 主线程会遍历得到DOM树,依次为树中的每个节点计算出它最终的样式,称之为Computed Style。
- 在这一过程中,很多预设值会变成绝对值,比如red会变成rgb(255,0,0);相对单位会变成绝对单位,比如em会变成px。
- 这一步完成后,会得到一棵带有样式的DOM树。
- 接下来是布局,布局完成后会得到布局树:
- 布局阶段会依次遍历DOM树的每一个节点,计算每个节点的几何信息。例如节点的宽高、相对包含块的位置。
- 大部分时候,DOM树和布局树并非一一对应。比如display: none;的节点没有几何信息,因此不会生成到几何树;又比如使用了伪元素选择器,虽然DOM树中不存在这些伪元素节点,但他们拥有几何信息,所以会生成到布局树中。还有匿名行盒、匿名块盒等等都会导致DOM树和布局树无法一一对应。
- 下一步是分层:
- 主线程会使用一套复杂的策略对整个布局树中进行分层。
- 分层的好处在于,将来某一个层改变后、仅会对该层进行后续处理,从而提升效率。
- 滚动条、折叠上下文、transform、opacity等样式都会或多或少的影响分层效果,也可以通过will-change属性更大程度的影响分层效果。
- 再下一步是绘制:
- 主线程会为每个层单独绘制指令集,用于描述这一层的内容该如何画出来。
- 完成绘制后,主线程将每个图层的绘制信息提交给合成线程,剩余工作将由合成线程完成。
- 合成线程首先对每个图层进行分块 、将其划分为更小的区域。它会从线程池中拿取多个线程来完成分块工作。
- 分块完成后进入光栅化阶段:
- 合成线程会将块信息交给GPU进程,以极高的速度完成光栅化。
- GPU进程会开启多个线程来完成光栅化,并且有限处理靠近视口区域的块。
- 光栅化的结果就是一块一块的位图。
- 最后一个阶段,就是画了:
- 合成线程拿到每个层、每个块的位图后,生成一个个指引信息。
- 指引会标识出每个位图应该画到屏幕的哪个位置,以及会考虑到旋转、缩放等变形。
- 变形发生在合成线程,与渲染主线程无关,这就是transform效率高的本质原因。
- 合成线程会把指引信息交给GPU进程,由GPU进程产生系统调用,提交给GPU硬件,完成最终屏幕的生成。
二、什么是reflow(回流)?
reflow的本质就是重新计算layout树。当进行了会影响布局树的操作后,需要重新计算布局树,会引发layout。
为了避免连续的多次操作导致布局树反复计算,浏览器会合并这些操作,当JS代码全部完成后再进行统一计算。所以,改动属性造成的reflow是异步完成的。
也同样因为如此,当JS获取到布局属性时,就可能造成无法获取到最新的布局消息。
浏览器在反复权衡下,最终决定获取属性立即reflow。
三、什么时repaint(重绘)?
repaint的本质就是重新根据分层信息计算了绘制指令。当改动了可见样式后就需要重新计算会引发repaint。
由于元素的布局信息也属于可见样式,所以reflow一定会引起repaint。
四、为什么transform的效率高?
因为transform既不会影响布局也不会影响绘制指令,它影响的只是渲染流程的最后一个“画”阶段,由于“画”阶段在合成线程中,所以transform的变化几乎不会影响渲染主线程。反之,渲染主线程无论如何忙碌,也不会影响transform的变化。
相关文章:
浏览器渲染原理(面试重点)
一、浏览器是如何渲染页面的 常见的简洁答案: 浏览器内核拿到内容后,渲染流程大致如下:解析HTML,构建Dom树;解析CSS,构建Render树;(将CSS代码解析成树形的数据结构,与D…...
C //练习 5-3 用指针方式实现第2章中的函数strcat。函数strcat(s, t)将t指向的字符串复制到s指向的字符串的尾部。
C程序设计语言 (第二版) 练习 5-3 练习 5-3 用指针方式实现第2章中的函数strcat。函数strcat(s, t)将t指向的字符串复制到s指向的字符串的尾部。 注意:代码在win32控制台运行,在不同的IDE环境下,有部分可能需要变更。…...
深度剖析Redis:从基础到高级应用
目录 引言 1、 Redis基础 1.1 Redis数据结构 1.1.1 字符串(String) 1.1.2 列表(List) 1.1.3 集合(Set) 1.1.4 散列(Hash) 1.1.5 有序集合(Sorted Set)…...
视频监控录像服务器(中心录像服务器)功能详细介绍
目 录 一、概述 (一)定义 (二)视频监控中心录像服务器 二、存储策略服务 (一)存储策略配置 1、 录入页面 2、 选择需要进行录像的视频 3、批量选择多个通道号 4、其他关键参数…...
SouthernBiotech抗荧光淬灭封片剂
荧光淬灭又称荧光熄灭或萃灭,是指导致特定物质的荧光强度和寿命减少的所有现象。引起荧光淬灭的物质称为荧光淬灭剂。SouthernBiotech专门开发的Fluoromount-G系列荧光封片剂是以甘油为基础,加入抗荧光淬灭剂,可明显降低荧光淬灭现象…...
[Excel]如何找到非固定空白格數列的條件數據? 以月份報價表單為例
在群組中看到上述問題,研判應是一份隨月份變動的產品報價表單,空白欄可能表示該月份價格與上個月份一致。這個問題是需要取得最近一次單價和倒數第二次單價,常用且實務的excel案例值得紀錄。 最近一次單價: INDEX($B2:$G2,1,LARGE(IF(ISBLAN…...
TypeScript进阶(二)深入理解装饰器
✨ 专栏介绍 TypeScript是一种由微软开发的开源编程语言,它是JavaScript的超集,意味着任何有效的JavaScript代码都是有效的TypeScript代码。TypeScript通过添加静态类型和其他特性来增强JavaScript,使其更适合大型项目和团队开发。 在TypeS…...
书生·浦语第三次作业
我最近在参加书生浦语大模型实战营,这是第三次作业打卡! 如果你也想两周玩转大模型微调,部署与测评全链路。报名链接:invite 书生浦语大模型实战营报名 邀请码可以填026014 一、基础作业:复现课程知识库助手搭建过程…...
GPT实战系列-LangChain + ChatGLM3构建天气查询助手
GPT实战系列-LangChain ChatGLM3构建天气查询助手 用ChatGLM的工具可以实现很多查询接口和执行命令,而LangChain是很热的大模型应用框架。如何联合它们实现大模型查询助手功能?例如调用工具实现网络天气查询助手功能。 LLM大模型相关文章: …...
LeetCode 2696.删除子串后的字符串最小长度:栈
【LetMeFly】2696.删除子串后的字符串最小长度:栈 力扣题目链接:https://leetcode.cn/problems/minimum-string-length-after-removing-substrings/ 给你一个仅由 大写 英文字符组成的字符串 s 。 你可以对此字符串执行一些操作,在每一步操…...
Xcode15 升级问题记录
这里写自定义目录标题 新版本Xcode15升级问题1:rsync error: some files could not be transferred (code 23) at ...参考 新版本Xcode15升级 下载地址:https://developer.apple.com/download/all/ 我目前使用的版本是Xcode15.2 我新创建了一个项目&…...
List、Set、Map有什么区别?
List、Set和Map是Java中的三种基本数据结构,它们在元素重复性、有序性和用途方面存在显著的区别。 元素重复性: List允许有重复的元素。任何数量的重复元素都可以在不影响现有重复元素的值及其索引的情况下插入到List集合中。 Set集合不允许元素重复。…...
centOS系统yum安装和卸载mongodb
0.1 什么是mongodb? 0.2 Mongodb是一个基于分布式文件存储的数据库。由C语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 0.3 Mongodb是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据…...
2023年12月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试
C/C++编程(1~8级)全部真题・点这里 第1题:数的输入和输出 输入一个整数和双精度浮点数,先将浮点数保留2位小数输出,然后输出整数。 时间限制:1000 内存限制:65536 输入 一行两个数,分别为整数N(不超过整型范围),双精度浮点数F,以一个空格分开。 输出 一行两个数,分…...
Python爬虫---Scrapy项目的创建及运行
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖 掘,信息处理或存储历史数据等一系列的程序中。 1. 安装scrapy: pip install scrapy 注意:需要安装在python解释器相同的位置,例如…...
PyTorch: torch.nn 子模块及其在循环神经网络中的应用
目录 torch.nn子模块详解 nn.utils.rnn.PackedSequence 参数说明 注意事项 示例代码 nn.utils.rnn.pack_padded_sequence 参数说明 返回值 注意事项 示例代码 nn.utils.rnn.pad_packed_sequence 参数说明 返回值 注意事项 示例代码 nn.utils.rnn.pad_sequence …...
【QT】自定义代理类
目录 1 我们为什么要使用自定义代理类? 2 自定义代理类的基本设计要求 3 自定义代理的功能 4 基于QSpinBox的自定义代理类 5 自定义代理类的使用 1 我们为什么要使用自定义代理类? 传统的模型-视图框架可以让我们实现逻辑展示相分离,我们…...
线程休眠、线程让步、线程优先级相关内容学习笔记
1、线程休眠 (1)sleep() 如果需要让当前正在执行的线程暂停一段时间,并进入阻塞状态(Timed_Waiting),则可以通过调用Thread类的静态sleep()方法来实现。 static void sleep(long millis):让当前正在执行的线…...
paddle指定运行gpu
在PaddlePaddle中指定使用GPU进行运行非常简单。首先,确保你的机器上已经安装了CUDA和cuDNN,并且正确配置了GPU环境。然后,按照以下步骤进行操作: 导入PaddlePaddle库: import paddle设置使用的设备为GPU:…...
Java异常及网络编程
异常续 throws关键字 当一个方法中使用throw抛出一个非RuntimeException的异常时,就要在该方法上使用throws声明这个异常的抛出。此时调用该方法的代码就必须处理这个异常,否则编译不通过。 package exception; /*** 测试异常的抛出*/ public clas…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
