DOM的渲染与优化

DOM渲染过程

面试题

在这里插入图片描述

DOM的渲染时机与渲染进程

渲染进程由五个线程组成

  • JS引擎线程

JS负责执行脚本,是单线程执行;由于脚本会对DOM进行修改,假如一个线程添加DOM,一个线程删除DOM。

  • GUI渲染线程

负责页面的解析与渲染;GUI线程和JS引擎线程是互斥的,当 JS 引擎执行时 GUI 线程会被挂起,GUI 更新会被保存在一个队列中等到 JS 引擎空闲时立即被执行。

  • 事件触发线程
  • 定时器触发线程
  • http异步请求线程

渲染进程的创建

  • 每次打开新标签页就会创建一个新的渲染进程。
  • 但是,当在该标签页中打开新的标签页,而且两个标签页属于同一站点时,会继续用同一渲染进程。

浏览器的渲染过程

1、解析HTML生成DOM树。遇到img标签时加载图片。
在这里插入图片描述
此时display:none属性的节点存在DOM树中
2、解析css文件生成CSSOM树。

解析CSS文件(遇到背景图片链接,不加载),生成渲染规则树。

3、加载JavaScript脚本,执行js代码。
4、根据DOM树和CSSOM树生成渲染树。

结合DOM树和CSSOM树来构建渲染树,然后遍历DOM树,加载对应DOM的样式背景图片。渲染树中不包含display:none属性的节点)

5、遍历渲染树开始布局。

计算每个节点的位置和大小信息,输出包含位置和样式的布局树。此时第一次计算节点大小和位置,该过程为布局,之后每一次触发布局称为回流。

6、绘制。开始渲染页面

对布局树进行分层形成分层树,对每一层分别进行绘制,不同图层渲染互不影响。

可以创建新的图层的节点:
在这里插入图片描述

  • 拥有层叠上下文属性的元素会单独为一层。比如属性为非static的position、z-index、filter、opacity等
  • 需要裁剪(clip)的地方也会创建图层

6、合成,将不同图层合并到一起,输出到屏幕,这个过程可以开启GUI加速

因此图片的渲染不会阻塞DOM渲染。

CSS、JS、DOM解析和渲染阻塞问题

DOM解析:DOM解析是指将HTML文件解析成为DOM树的过程。
DOM渲染:是指将CSSOM树和DOM树结合生成render树,再将渲染树渲染到页面的过程。

  • CSS的解析不会阻塞DOM解析,但会阻塞DOM的渲染。CSS的解析与DOM的解析并行。
  • 同步的JS脚本执行会阻塞DOM的解析(由于JS引擎和渲染线程是互斥的)

CSS加载会阻塞后面JS的执行

补充知识
1、浏览器解析DOM时会预先加载具有引用标记的外部资源(例如有src标记的<script>标签),在解析到此标签时就直接运行,无需再加载资源,提高运行效率。
2、浏览器无法预先知道脚本的内容,因此在碰到<script>标签时,会触发页面渲染,确保<script>内能获取到DOM的新样式。

JS阻塞DOM问题怎么解决–JS的三种异步加载方式

defer和async属性只会改变脚本的执行时机,脚本的加载不受影响,也不会影响页面的解析

1、没有属性的script标签
页面解析遇到script标签时,会暂停解析,转而去加载和执行js脚本。会阻塞页面的解析。
在这里插入图片描述

2、defer属性的script标签
defer属性代表异步加载,延迟执行,会在HTML解析完成之后再执行脚本。会在DOMContentLoaded事件触发之前完成。
在这里插入图片描述
优先级高于DOMContentLoaded事件,脚本执行完成之后再触发DOMContentLoaded事件。

3、async属性的script标签
加载和执行都是异步,在脚本下载完之后立即执行。
页面没解析完时,会等脚本执行完再解析页面。
在这里插入图片描述
页面解析完成会直接执行脚本。
在这里插入图片描述

DOMContentLoaded和Load事件

对浏览器来说,页面加载主要有DOMContentLoaded和Load两个事件

  • DOMContentLoaded:当页面解析完成后即DOM加载完成之后触发该事件.defer优先级高于该事件,等脚本执行完再触发该事件
  • load事件:等页面所有资源加载完才会触发,例如js、CSS、图片视频等。

渲染优化

1、从回流和重绘进行优化

  • GPU加速

transform
opacity
will-change

  • JS优化

对于scroll等事件进行防抖或节流处理
对于offset等敏感属性用变量缓存(每次获取offset时会触发一次布局即回流)
避免频繁的改动style,采用修改class的方式

2、其他渲染阶段优化

  • 使用webworker多线程,将计算量大的运算放在worker线程处理,避免js阻塞页面渲染。
  • 开启cdn加载css等静态资源,即加快css的加载速度。
  • 避免动画实现中丢帧造成卡顿现象,尽量不用计时器实现动画,而采用window.requestAnimationFrame(回调)
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值