你知道HTML、CSS、JS文件在浏览器中是如何转化成页面的吗?
zhezhongyun 2025-05-16 18:01 15 浏览
在前面一篇文章:「高频面试题」浏览器从输入url到页面展示中间发生了什么 中,我们有对浏览器的渲染流程做了一个概括性的介绍,今天这篇文章我们将深入学习这部分内容。
对于很多前端开发来说,平常做工主要专注于业务开发,对浏览器的渲染阶段可能不是很了解。实际上这个阶段很重要,了解浏览器的渲染过程,能让我们知道我们写的HTML、CSS、JS代码是如何被解析,并最终渲染成一个页面的,在页面性能优化的时候有相应的解决思路。
我们先来看一个问题:
HTML、CSS、JS文件在浏览器中是如何转化成页面的?
如果你回答不上来,那就往下看吧。
按照渲染的时间顺序,渲染过程可以分为下面几个子阶段:构建DOM树、样式计算、布局阶段、分层、栅格化和合成显示。
下面详细看下每个阶段都做了哪些事情。
1. 构建DOM树
HTML文档描述一个页面的结构,但是浏览器无法直接理解和使用HTML,所以需要通过HTML解析器将HTML转换成浏览器能够理解的结构——DOM树。
HTML文档中所有内容皆为节点,各节点之间有层级关系,彼此相连,构成DOM树。
构建过程:读取HTML文档的字节(Bytes),将字节转换成字符(Chars),依据字符确定标签(Tokens),将标签转换成节点(Nodes),以节点为基准构建DOM树。参考下图:
打开Chrome的开发者工具,在控制台输入 document 后回车,就能看到一个完整的DOM树结构,如下图所示:
在控制台打印出来的DOM结构和HTML内容几乎一样,但和HTML不同的是,DOM是保存在内存中的树状结构,可以通过JavaScript来查询或修改其内容。
2. 样式计算
样式计算这个阶段,是为了计算出DOM节点中每个元素的表现样式。
2.1 解析CSS
CSS样式可以通过下面三种方式引入:
- 通过link引用外部的CSS文件
- style 标签内的CSS
- 元素的style属性内嵌的CSS
和HTML一样,浏览器无法直接理解纯文本的CSS样式,需要通过CSS解析器将CSS解析成 styleSheets 结构,也就是我们常说的 CSSOM树。
styleSheets结构同样具备查询和修改功能:
document.styleSheets
2.2 属性值标准化
属性值标准化看字面意思有点不好理解,我们通过下面一个例子来看看什么是属性值标准化:
在写CSS样式的时候,我们在设置color属性值的时候,经常会用white、red等,但是这种值浏览器的渲染引擎不容易理解,所以需要将所有值转换成渲染引擎容易理解的、标准化的计算值,这个过程就是属性值标准化。
white标准化后的值为 rgb(255, 255, 255)
2.3 计算DOM树中每个节点的样式
完成样式的属性值标准化后,就需要计算每个节点的样式属性,这个阶段CSS有两个规则我们需要清楚:
- 继承规则:每个DOM节点都包含有父节点的样式
- 层叠规则:层叠是CSS的一个基本特征,是一个定义了如何合并来自多个源的属性值的算法。
样式计算阶段是为了计算出DOM节点中每个元素的具体样式,在计算过程中需要遵守CSS的继承和层叠两个规则。
该阶段最终输出的内容是每个DOM节点的样式,并被保存在 ComputedStyle 的结构中。
3. 布局阶段
经过上面的两个步骤,我们已经拿到了DOM树和DOM树中元素的样式,接下来需要计算DOM树中可见元素的几何位置,这个计算过程就是布局。
3.1 创建布局树
在DOM树中包含了一些不可见的元素,例如 head 标签,设置了 display:none 属性的元素,所以我们需要额外构建一棵只包含可见元素的布局树。
构建过程:从DOM树的根节点开始遍历,将所有可见的节点加到布局树中,忽略不可见的节点。
3.2 布局计算
到这里我们就有了一棵构建好的布局树,就可以开始计算布局树节点的坐标位置了。从根节点开始遍历,结合上面计算得到的样式,确定每个节点对象在页面上的具体大小和位置,将这些信息保存在布局树中。
布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小。
4. 分层
现在我们已经有了布局树,也知道了每个元素的具体位置信息,但是还不能开始绘制页面,因为页面中会有像3D变换、页面滚动、或者用 z-index 进行z轴排序等复杂效果,为了更方便实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree)。
在Chrome浏览器中,我们可以打开开发者工具,选择 Elements-Layers 标签,就可以看到页面的分层情况,如下图所示:
浏览器的页面实际上被分成了很多图层,这些图层叠加后合成了最终的页面。
到这里,我们构建了两棵树:布局树和图层树。下面我们来看下这两棵树之间的关系:
正常情况下,并不是布局树的每个节点都包含一个图层,如果一个节点没有对应的图层,那么这个节点就从属于父节点的图层。
那节点要满足什么条件才会被提升为一个单独的图层?只要满足下面其中一个条件即可:
- 拥有层叠上下文属性的元素会被提升为单独的一个图层
- 需要剪裁(clip)的地方也会被创建为图层。
5. 图层绘制
构建好图层树之后,渲染引擎就会对图层树中的每个图层进行绘制。
渲染引擎实现图层绘制,会把一个图层的绘制拆分成很多小的绘制指令,然后将这些指令按照顺序组成一个绘制列表。
6. 栅格化(raster)操作
绘制一个图层时会生成一个绘制列表,这只是用来记录绘制顺序和绘制指令的列表,实际上绘制操作是由渲染引擎中的合成线程来完成的。
通过下图来看下渲染主线程和合成线程之间的关系:
当图层的绘制列表准备好后,主线程会把该绘制列表提交给合成线程,合成线程开始工作。
首先合成线程会将图层划分为图块(tile),图块大小通常是 256256 或者 512512。
然后合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图。而图块是栅格化执行的最小单位。渲染进程维护了一个栅格化的线程池,所有的图块栅格化都是在线程池内执行的,运行方式如下图所示:
7. 合成和显示
一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。
浏览器进程里面有一个名字叫做 viz 的组件,用来接收合成线程发过来的 DrawQuad 命令,然后根据命令执行。 DrawQuad 命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上。
多年开发老码农福利赠送:网页制作,网站开发,web前端开发,从最零基础开始的的HTML+CSS+JavaScript。jQuery,Vue、React、Ajax,node,angular框架等到移动端小程序项目实战【视频+工具+电子书+系统路线图】都有整理,需要的伙伴可以私信我,发送“前端”等3秒后就可以获取领取地址,送给每一位对编程感兴趣的小伙伴
8. 总结
一个完整的渲染流程可以总结如下:
- 1、渲染进程将HTML内容转换为浏览器能够读懂的DOM树结构。
- 2、渲染引擎将CSS样式表转化为浏览器可以理解的styleSheets,计算出DOM节点的样式。
- 3、创建布局树,并计算所需元素的布局信息。
- 4、对布局树进行分层,并生成分层树。
- 5、为每个图层生成绘制列表,并将其提交到合成线程。
- 6、合成线程将图层分图块,并栅格化将图块转换成位图。
- 7、合成线程发送绘制图块命令给浏览器进程。浏览器进程根据指令生成页面,并显示到显示器上。
渲染过程中还有两个我们经常听到的概念:重排和重绘。在这篇文章中就不细说了,下一篇文章再详细介绍。
- 上一篇:Flask简介
- 下一篇:软网推荐:快速变身 图片数学公式转换可编辑文档
相关推荐
- 饿了么面试官:实现一下 Element-UI 官网的主题切换动画!
-
最近看到ElementPlus官网上的切换主题方式非常有趣,这是一个过渡的动画效果所以在网上查了一番,找到基本的实现方法实现基本效果首先我们起一个html文件,写一个按钮,以及简单的背景颜色切...
- 强大而好用的选择器:focus-within
-
伪类和伪元素在开发网页样式中,选择器必不可少,而且选择器也是在开发css中非常重要的内容,包括常用的类选择器,id选择,同时还有伪类,伪类选择器最大的特点就是冒号开头。平时也经常会有小伙伴问到,在使用...
- 令程序员惊叹的一些CSS3效果库
-
还在寻找那些CSS3的效果库吗?如果你的答案是肯定的,并且目前没有找到,那么你一定不能错过小编为大家收集的这些CSS3效果库,这是一个令你兴奋的集合!最新的CSS3都配备了新的特性,来设计创建动画和互...
- 伪元素黑魔法:一个替代onerror解决图片加载失败的方案
-
问题的引出是这样的,在一个项目中有大量的页面主体是table做数据展示,所以就封装了一个table的组件,提供动态渲染的方案。有个问题是数据类型中有图片,对于图片的加载失败我们需要做容错。一般我们的思...
- 前端 - 如何通过CSS修改图片透明度
-
如果在图片上显示文字,经常会遇到这个情况,就是当文字和背景颜色差不多时,文字会看不清楚,我们一般通过给文字加textshadow或者修改图片的透明度来让文字显示更加突出。我们今天说一下透明度的问题,...
- CSS元素居中方法完全指南
-
这里是工作狂的聚集地职场学术新媒体设计极客专门治愈处女座强迫症。本文为CSS入门翻译redman9原载CSS-Trick人们经常抱怨在CSS中居中元素的问题,其实这个问题并不复杂,只是因为方法众...
- CSS图像 hover 动画效果
-
点击页底“阅读原文”下载原码CSSHover在网页设计中是极为常用的一个CSS效果,只要你有创造力,都可以让Hover变得更多姿多彩,今天我们主要分享40多款使用CSSHOVER完成...
- 前端能限制用户截图吗?
-
摘要:在某些业务场景下,保护屏幕信息的私密性,防止用户随意截图分享,成为了前端开发者的一个棘手需求。但浏览器和操作系统的设计,真的允许网页开发者完全掌控用户的截图行为吗?本文将深入探讨前端限制截图的...
- 每天一个CSS小技巧 - 不规则投影
-
当我们想给一个矩形或者其他能用border-radius生成的形状加投影时,box-shadow的表现都很棒的。但是,当元素添加可一些伪元素或半透明的装饰之后,border-radius会无视这些。这...
- Web开发中10个有用的免费CSS代码
-
在本文中主要展示了在Web开发中一些免费但是非常有用的代码,开发人员可以下载它们来简化工作流程。在这个集合中的所有代码都是经过精挑细选的,对于开发人员来说非常有用。在开发一个网站时,这些代码将节省大量...
- 什么是伪类和伪元素?两者有什么区别?单一冒号和双冒号有何不同
-
https://juejin.im/post/5df1e312f265da33d039d06d?utm_source=bigezhang.com#comment伪类伪类存在的意义是为了通过选择器找到那...
- CSS2与CSS3中常用的伪类汇总大全
-
CSS2与CSS3中有非常多的伪类,可以用于实现各种强大的、酷炫的功能。有用于选择标签状态的,如:a:linka:hoverinput:checkedinput:focus等;也有用于根据结构选...
- 实用!这8个CSS工具可以提升编程速度
-
作为网页设计师,为了在预期的时间内能完成项目,前期肯定是要进行大量练习的。但是如果你花了大量的时间在编写CSS代码上,那无疑是浪费时间。工欲善其事必先利其器,聪明的设计师善于利用工具提升他们的编码效率...
- 《丝路传说怀旧版》宠物融合丹:属性加成与技能继承要点
-
在《丝路传说怀旧版》中,宠物融合丹是优化宠物属性与技能的核心道具,其使用需结合技能继承规则、品质提升机制及资源规划策略。以下是关键要点分析一、属性加成机制品质提升与属性增长品质阶梯:宠物分为白、绿、蓝...
- Python 3.14 t-string 要来了,它与 f-string 有何不同?
-
Python最近出了个大新闻:PEP-750t-string语法被正式采纳了!这意味着Python将在今年10月发布的3.14版本中引入一种新的字符串前缀t,称为模板字符串(Tem...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML常用标签 (29)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)
- HTML button formtarget 属性 (30)
- CSS 水平对齐 (Horizontal Align) (30)