DOM树:DOM的层级关系、节点关系
页面之所以能渲染
- 从服务器获取需要渲染的内容(URL解析/DNS/TCP/HTTP...)
- 浏览器基于自己的渲染引擎(例如:webkit/gecko/trident/blink...)开始自上而下加载渲染代码
性能优化
CRP性能节点优化:根据渲染的每个关键节点,提高关键节点的优化效率。
- 减少DOM树渲染的时间(HTML层级不要太深,标签语义化...)
- 减少CSSOM树渲染时间(选择器是从右向左解析,所以尽可能减少选择器的层级【less/sass中的层级嵌套虽然好用,但是是一个大坑】)
- 一般会把CSS放在页面的开始位置(提前请求资源,用link,别用@import,对于移动端来讲,如果CSS比较少,尽可能采用内嵌式即可...)
- 为了避免白屏,可以进来第一件事,快速生成一套 loding 的渲染树(前端骨架屏);服务器的SSR骨架屏提高的渲染是避免了客户端再次单独请求数据,而不是样式和结构上的(首屏处理);
- 把JS放在页面底部,尽可能使用defer、async
- 减少HTTP的请求次数和请求大小
.......
布局,回流,重新布局
构建DOM树、CSSOM树、RENDER树
- 转换:把进制数据转换为代码字符串
- 词法分析:依托w3c规范生成对应的节点
- DOM/CSSOM构建:根据节点生层对应的树
【DOM树】
【CSSOM树】
【Render-Tree渲染树】
总结步骤:
- 处理 HTML 标记,构建 DOM 树
- 处理 CSS 标记,构建 CSSOM 树
- 将 DOM 树和 CSSOM 树融合成渲染树
- 根据生成的渲染树,计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流 => 布局(Layout)或 重排(reflow)
- 根据渲染树以及回流得到的几何信息,得到节点的绝对像素 => 绘制(painting)或栅格化(rasterizing)
优化方案:
- 标签语义化和避免深层次嵌套
- CSS选择器渲染是从右到左
- 尽早尽快地把CSS下载到客户端(充分利用HTTP多请求并发机制)
style
link
@import
- 放到顶部
- 避免阻塞的JS加载
defer
:请求过程中,遇到script,要请求外部资源文件,会单独发一个请求,相当于开启一个新的http请求线程,不会阻碍渲染,当所有的DOM树生成完了,跟link一样,js资源回来后,按照js导入的优先级顺序,依次去渲染js代码。【js中有相互依赖顺序的。】async
:和defer的相同点,开辟一个新的http请求线程。当请求资源回来后,立即执行代码。- 放到底部
【绿色:页面渲染;蓝色:请求网络资源;红色:执行代码。】
-
减少DOM的回流和重绘
布局,回流,重新布局