浏览器渲染原理

渲染过程

1.浏览器接收到HTML文件并转换为DOM树

当我们打开一个网页时,浏览器都会去请求对应的HTML文件。我们平时写的JS,CSS,HTML文件都是字符串,但是计算机硬件是不理解这些字符串的,所以在网络中传输的内容其实都是0和1这些字节数据。当浏览器接受到这些字节数据以后,他就会将这些字节数据转换为字符串,也就是我们写的代码。

当数据转换为字符串以后,浏览器会讲这些字符串通过词法分析转换为标记(token),这一过程在词法分析中叫做标计划。

简单来说,标记还是字符串,是构成代码的最小单位。这一过程会将代码分拆成一块一块,并给这些内容打上标记,便于理解这些最小单位的代码是什么意思

当结束标记化后,这些标记会紧接着转换为Node,最后这些Node会根据不同Node之间的联系构建一颗DOM树

2.将CSS文件转换成CSSOM树

在解析HTML文件的时候,浏览器还会遇到CSS和JS文件,这时候浏览器也会去下载并解析这些文件

在这一过程中,浏览器会确定下每一个节点的样式到底是什么,并且这一过程是很消耗资源的。因为样式你可以自行设置给某个节点,也可以通过继承获得。在这一过程,浏览器得递归CSSOM树,然后确定具体的元素到底是什么样式。所以我们应该尽可能的避免写过于具体的CSS选择器,然后对于HTML来说也尽量少的添加无意义标签,保证层级扁平

3.生成渲染树

当我们生成DOM树和CSSOM树以后,就需要将这两颗树组合为渲染树

  • 渲染树只会包括需要显示的节点和这些节点的样式信息,如果某个节点为display:none,那么就不会在渲染树中显示
  • 当浏览器生成渲染树以后,就会根据渲染树来进行布局(也可以叫做回流),然后调用GPU绘制,合成图层,显示在屏幕上。

为什么操作DOM慢

因为DOM是属于渲染引擎中的东西,而IS又是JS引擎中的东西。当我们通过JS操作DOM时,其实这个操作涉及到了两个线程之间的通信,那么势必会带来一些性能上的损耗,同时可能会带来重绘回流的情况

面试题:插入几万个DOM,如何实现页面不卡顿

  • 对于这道题目来说,首先我们肯定不能一次性把几万个 DOM 全部插入,这样肯定会造成卡顿,所以解决问题的重点应该是如何分批次部分渲染DOM。大部分人应该可以想到通过 requestAnimationFrame 的方式去循环的插DOM,其实还有种方式去解决这个问题:虚拟滚动(virtualized scroller)。
  • 这种技术的原理就是只渲染可视区域内的内容,非可见区域的那就完全不渲染了,当用户在滚动的时候就实时去替换渲染的内容

什么情况阻塞渲染

  • 首先渲染的前提是生成渲染树,所以 HTML 和 CSS 肯定会阻塞渲染。如果你想渲染的越快,你越应该降低一开始需要渲染的文件大小,并且扁平层级,优化选择器。
  • 然后当浏览器在解析到 script 标签时,会暂停构建 DOM,完成后才会从暂停的地方重新开始。也就是说,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS文件,这也是都建议将 script 标签放在 body 标签底部的原因
  • 当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性
  • 当 script 标签加上 defer 属性以后,表示该 JS 文件会并行下载,但是会放到 HTML 解析完成后顺序执行,所以对于这种情况你可以把 script标签放在任意位置。
  • 对于没有任何依赖的 JS 文件可以加上 async 属性,表示 JS 文件下载和解析不会阻塞渲染

重绘(Repaint)和回流(Reflow)

  • 重绘是当节点需要改变外观而不会影响布局
  • 回流是布局或者几何属性需要改变
  • 回流必定会发生重绘,重绘不一定引发回流。回流所需的成本比重绘高的多,改变父节点里的子节点很可能会导致父节点的一系列回流
以下几个动作可能会导致性能问题
  • 改变window大小
  • 改变字体
  • 添加或删除样式
  • 文字改变
  • 定位或者浮动
  • 盒模型

减少重绘和回流

  • 使用 transform 替代 top
  • 使用 visibility 替换display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局)
  • 不要把节点的属性值放在一个循环里当成循环里的变量
for(let i = 0; i < 1000; i++) {
    // 获取 offsetTop 会导致回流,因为需要去获取正确的值
    console.log(document.querySelector('.test').style.offsetTop)
}
  • 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局
  • CSS 选择符从右往左匹配查找,避免节点层级过多
  • 将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点。比如对于 video 标签来说,浏览器会自动将该节点变为图层

我们可以通过以下几个常用属性可以生成新图层:will-change、video、iframe 标签

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值