结合上图,一个完整的渲染流程大致可总结为如下:
- 渲染进程将 HTML 内容转换为能够读懂的DOM树结构。
- 渲染引擎将 CSS 样式表转化为浏览器可以理解的styleSheets,计算出 DOM 节点的样式。
- 创建布局树,并计算元素的布局信息。
- 对布局树进行分层,并生成分层树。
- 为每个图层生成绘制列表,并将其提交到合成线程。
- 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
- 合成线程发送绘制图块命令DrawQuad给浏览器进程。
- 浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。
思考题
1、关于“重排”,“重绘”和“合成”?
如果修改了元素的样式高度或宽度等会重新布局,然后布局后面所有的操作都会重新执行一遍,这是重排。 如果修改的是背景色等,不需要布局的,也不需要分层,直接到绘制阶段,这是重绘。 如果我们使用css的transform实现动画效果,这时既不需要重新布局,也不需要重新绘制(只需要合成线程进行合成就行了),直接在非主线程上执行合成动画操作,这是合成。
2、减少重排重绘的方法:
使用 class 操作样式,而不是频繁操作 style
避免使用 table 布局
批量dom 操作,例如 createDocumentFragment,或者使用框架,例如 React
Debounce window resize 事件
对 dom 属性的读写要分离
will-change: transform 做优化