当我们打开一个网页时,背后发生了什么?浏览器如何将HTML
、CSS
和JavaScript
代码转换成我们看到的精美页面?
概述:五步渲染流程
浏览器渲染网页可以简化为五个关键步骤:
- 解析HTML,构建DOM树 - 将HTML标签转换为文档对象模型
- 解析CSS,构建CSSOM树 - 处理样式信息形成
CSS
对象模型 - 合并成渲染树 - 将
DOM
和CSSOM
结合,排除不可见元素 - 布局计算 - 计算每个元素在屏幕上的确切位置和大小
- 绘制显示 - 将布局好的内容绘制到屏幕上,最终呈现给用户
其中第四步和第五步是最耗时的部分,这两步合起来就是我们通常所说的"渲染"。
深入渲染的五个阶段
第一步:解析HTML,构建DOM树
当浏览器接收到HTML
文档时,它会立即开始解析工作。解析器会将HTML
标签转换为一个树状结构------DOM
(文档对象模型)树。
DOM
树有两个主要作用:
- 作为下一阶段渲染树的输入
- 提供
JavaScript
与网页交互的接口(如常用的getElementById
等方法)
遇到脚本时的处理 : 当解析器遇到<script>
标签时,会发生四件事:
HTML
解析暂停- 如果是外部脚本,从网络获取代码
- 将控制权交给
JavaScript
引擎执行代码 - 执行完毕后恢复
HTML
解析
优化建议:
- 将
<script>
标签放在页面底部,加速首屏渲染 - 使用
defer
(延迟执行,DOM构建完成后执行)或async
(异步加载和执行)属性优化脚本加载
第二步:解析CSS,构建CSSOM树
与此同时,浏览器也会处理CSS
样式,构建CSSOM
(CSS
对象模型)树。虽然CSS
不会修改文档结构,但CSSOM
树的构建仍然是阻塞性 的------浏览器会等待CSSOM
构建完成后才进行渲染。
优化建议:
- 尽快加载
CSS
样式表 - 使用
media type
和media query
区分不同样式表,将非关键CSS
标记为非阻塞资源
第三步:合并DOM和CSSOM形成渲染树
渲染树只包含可见内容------不会包含如<head>
、display: none
元素等不可见节点。这一步将DOM
的內容和CSSOM
的样式信息结合,确定每个节点应该如何显示。
第四步:布局计算
也称为"重排"(reflow
),浏览器计算渲染树中每个节点的确切位置和大小。这个过程考虑各种布局因素,如定位方式、浮动、边距等。
第五步:绘制与合成
最后一步,浏览器将布局计算后的节点转换为实际像素,绘制到屏幕上。现代浏览器会使用GPU
加速绘制过程,特别是对于动画和复杂视觉效果。
性能优化关键点
理解Load和DOMContentLoaded事件
- DOMContentLoaded:HTML文档完全加载和解析后触发,无需等待样式表、图像和子框架完成加载
- Load :整个页面及所有依赖资源(如
CSS
、图片)完全加载完成后触发
利用图层提升性能
浏览器可以将特定元素提升为单独图层,独立渲染这些图层可以提高性能。以下属性可以创建新图层:
3D
变换属性:translate3d
、translateZ
will-change
属性(提前告知浏览器元素可能的变化)<video>
和iframe>
元素- 使用
CSS
动画实现透明度变化 position: fixed
定位元素
注意:图层不是越多越好,过多图层反而会降低性能。
重绘(Repaint)与回流(Reflow)
- 重绘:元素外观改变但不影响布局(如修改颜色、背景)
- 回流:元素的布局或几何属性改变(如修改宽度、位置)
回流成本远高于重绘,而且一个元素回流可能导致父元素及周围元素也需要回流。
减少重绘和回流的实用技巧
- 使用
transform
替代定位属性 (如用translate
代替top/left
) - 使用
visibility: hidden
替代display: none
(前者只引起重绘,后者引起回流) - 批量修改DOM :先使元素脱离文档流(
display: none
),进行多次修改,再带回文档流 - 避免在循环中读取布局属性 (如
offsetTop
、offsetWidth
) - 避免使用table布局 - 小小改动可能导致整个表格重新布局
- 优化CSS选择器 - 从右向左匹配,避免过于复杂的选择器
- **使用
requestAnimationFrame
**优化动画性能
现代浏览器的渲染调度
现代浏览器会智能调度渲染任务:
- 每秒60帧(每16ms一帧)的刷新率
resize
和scroll
事件自带节流(至少16ms触发一次)- 使用
requestIdleCallback
在空闲时间执行非紧急任务
结语
理解浏览器渲染原理对于前端开发者至关重要。通过优化HTML结构、合理使用CSS和JavaScript,我们可以显著提升网页性能,为用户提供更流畅的浏览体验。
记住关键点:减少重绘回流、合理利用图层、优化资源加载顺序,你的网页将会飞起来!