浏览器的渲染方式
构建 DOM 树
浏览器请求到 html 代码后,在生成 DOM 的最开始阶段,并行发起 css、图片、js 的请求。(解码->令牌化->词法分析->dom 树创建)构建 CSSOM
css 文件加载完成,开始构建 CSSOM(CSSOM 只输出包含有样式的节点)生成渲染树(Render Tree)
CSSOM 构建结束后,和 DOM 一起生成 Render Tree计算渲染树布局(Layout)
有了 Render Tree,浏览器已经能知道网页中有哪些节点,各个节点的 CSS 定义以及他们的从属关系。依照盒子模型,计算出每个节点在屏幕中的位置及尺寸。将布局 Paint 绘制到屏幕上
布局之后,浏览器知道哪些节点要显示,每个节点的 CSS 属性是什么,每个节点在屏幕中的位置。所以接下来按照算出来的规则,通过显卡,把内容画在屏幕上。
页面渲染优化
避免 CSS 阻塞渲染:
由于 CSSOM 负责存储渲染信息,浏览器就必须保证在合成渲染树之前,CSSOM 是完备的,这种完备是指所有的 CSS(内联、内部和外部)都已经下载完,并解析完,只有 CSSOM 和 DOM 的解析完全结束,浏览器才会进入下一步的渲染。CSS 阻塞渲染意味着,在 CSSOM 完备前,页面将一直处理白屏状态,这就是为什么样式放在 head 中,仅仅是为了更快的解析 CSS,保证更快的首次渲染。
避免 JS 阻塞页面:
JS 可以操作 DOM 来修改 DOM 结构,可以操作 CSSOM 来修改节点样式,这就导致了浏览器在解析 HTML 时,一旦碰到 script,就会立即停止 HTML 的解析,也阻塞了其后的 CSS 解析,整个解析进程必须等待 JS 的执行完成才能够继续。从性能角度上讲,将 script 放在页面底部,也就合情合理了。
减少重绘( Repaint
):
当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为 repaint。
- 重绘(repaint): 当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要 UI 层面的重新像素绘制,因此 损耗较少。
触发重绘
- DOM 改动
- CSS 改动
减少重排( Reflow
):
DOM 结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为 reflow。
- 回流(
reflow
): 当元素的尺寸、结构或触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。
触发重排
- 当增加、删除、修改
DOM
节点时,会导致reflow
或repaint
- 当移动
DOM
的位置,或是插入动画的时候 - 当修改 CSS 样式的时候
- 当 Resize 窗口的时候,或是滚动的时候
- 当修改网页的默认字体时
重排和重绘的区别
他们的区别很大:
回流必将引起重绘,而重绘不一定会引起回流。比如:只有颜色改变的时候就只会发生重绘而不会引起回流
当页面布局和几何属性改变时就需要回流
比如:添加或者删除可见的 DOM 元素,元素位置改变,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变
最小化重绘和重排
避免频繁使用
style
,而是采用修改class
的方式。批量修改
DOM
:使用文档片段创建一个子树,然后再拷贝到文档中(document.fragment)使用 createDocumentFragment 进行批量的 DOM 操作。缓存布局信息
对于
resize
、scroll
等进行防抖/节流处理。创建动画或者移动元素位置时尽量使用
transform: translate
使用字体图标 iconfont 代替图片图标:
图片会增加网络请求次数,从而拖慢页面加载时间
iconfont 可以很好的缩放并且不会添加额外的请求
降低 css 选择器的复杂度:浏览器读取选择器,遵循的原则是从选择器的右边到左边读取。
- 减少嵌套:最多不要超过三层,并且后代选择器的开销较高,慎重使用
- 避免使用通配符,对用到的元素进行匹配即可
- 利用继承,避免重复匹配和定义
- 正确使用类选择器和 id 选择器
- 本文作者: luckyship
- 本文链接: https://luckyship.github.io/2021/05/12/2021-05-12-browser-render/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!