浏览器渲染机制
# 常见的浏览器渲染引擎
# 渲染引擎
能加载HTML/css/javascript文本和对应资源文件转换成图像结果
# 渲染器种类
渲染引擎 | 浏览器 |
---|---|
Trident | IE、Edge(旧) |
Geoko | Firefox |
Webkit | Safari |
Blink(Webkit form) | Chrome, Opera,Edge(新) |
# 浏览器的工作流程
webkit的主要流程
我们围绕这张图,看下浏览器是如何渲染页面的技术细节
- 解析dom,生成dom tree(并行)
- 解析css,生成cssom tree(并行)
- 将dom树和cssom规则合并在一起生成渲染树
- 遍历开始布局,计算节点位置大小,生成布局树
- GPU工作,按照布局树规则在屏幕上绘制页面
# 构建dom树
浏览器接收到html文档之后,遍历文档所有节点,根据深度优先遍历的算法,HTML解析器将HTML标记解析成DOM Tree(就是我们审查元素时的层级结构)。
# 构建csscom树
css Parse 将每一css 文件都解析成一个styleSheet对象,每个对象包含style Rules,这个也就是所谓的cssom。
不知道大家在这里会不会有和我一样的疑问,既然cssom是为了dom而存在的,为什么不在dom解析的时候,就将对应的样式添加到dom上呢?而且css具有很高的优先级,css会阻塞任何的渲染,在css解析前,页面上不会有任何反应。我想到的解释是,如果css解析之前就渲染了页面,那么每个页面都是无样式的,过一会却突然有了样式,整个页面的渲染就会很糟糕。
# 生成Render Tree
这个时候,浏览器会将DOM和CSSDOM结合起来生成Render Tree(渲染树)
# 生成布局树 Layout
创建渲染树之后,构建布局树,分两个部分:
# 回流(reflow)
浏览器布局发生改变,需要倒回去重新渲染,这个过程叫做回流(reflow),从root往下递归计算,来确认是渲染树的整体还是一部分发生改变。
引起回流的一些操作
- 页面
第一次
渲染(初始化) - DOM树变化(如:增删节点)
- Render树变化(如:padding改变)
- 浏览器窗口
resize
- 获取元素的某些属性:
offsetLeft
、offsetTop
、offsetWidth
、offsetHeight
、scrollTop/Left/Width/Height
、clientTop/Left/Width/Height
、调用了getComputedStyle()
# 重绘(repaint)
改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸和位置没有发生改变,这个过程叫做重绘(repaint)
回流必定引起repaint重绘,重绘可以单独触发
- 背景色、颜色、字体改变(注意:字体大小发生变化时,会触发回流)
# 优化
# 减少reflow、repaint触发优化
- 用transform做形变和位移可以减少reflow
- 避免逐个修改节点样式,尽量一次性修改
- 使用DocumentFragment将需要多次修改的DOM元素缓存,最后一次性append到真实DOM中渲染
- 可以将需要多次修改的DOM元素设置display:none,操作完再显示。(因为隐藏- - 元素不在render树内,因此修改隐藏元素不会触发回流重绘)
- 避免多次读取某些属性
- 通过绝对位移将复杂的节点元素脱离文档流,形成新的Render Layer,降低回流成本
# 浏览器内核(渲染进程)中线程之间的关系
为了防止渲染出现不可预期的结果,GUI线程和JS引擎线程互斥
js是可以操作dom的,如果修改时,在GUI正在渲染,这个时候GUI线程会被挂起,保存在一个队列中,等待js引擎空闲时立即被执行
问:CSS加载会阻塞DOM树的解析,渲染吗? 这里说的是头部引入css的情况
答:根据上面的流程图可以看到,dom树和cssom是互相解析的,但是在生成render树的时候,需要等待css解析完,所以CSS加载不会阻塞DOM树的解析,但是会阻塞DOM树的渲染
。
问:CSS和JS会互相阻塞吗?
答:因为GUI线程和JS引擎线程互斥,我们可以分别尝试分别把js和css放在上面
- script标签在style上面使用alert语句,页面不加载,阻塞了css解析
- style在面,使用慢网速加载cdn的css样式,样式展示前,js不执行,阻塞了js的执行
结论,CSS加载会阻塞后面JS语句的执行,所以在开始学习前端时,会建议大家将script标签放在body之后,防止影响页面渲染。
# 相关链接
https://juejin.cn/post/6940210613662531592