上次写了浏览器渲染出网页的过程,想到了一些代码优化的小知识,当然了,我学识太浅,想到了还是太少了,所以这篇文章就长期更新啦。以后可能还有其他的框架如React等单独的代码优化的知识,毕竟这样的知识实在是太多了,一篇文章也会有些乱。
个人能力有限,文中可能会有很多错误之处,希望大家看到后可以在评论里指出来,一起进步,谢谢啦。
那下面开始正文。
操作DOM比较慢的原因
在浏览器中,DOM是属于渲染引擎的,JS是属于JS引擎的,JS来操作DOM,也就是两个引擎之间进行通信。
浏览器中,这个通信是需要通过接口来实现的,而每次使用这个接口就会产生一些性能的损耗。
async和defer的作用和区别
在引用JS的时候,会有三种使用方法,1. 直接使用;2. async加载;3. defer加载
在浏览器中会出行下面这样的区别
图画的不太好,见谅哈。
1. 直接使用
<script src = "script.js"></script>
在浏览器中遇到JS代码,就会阻塞HTML解析,进行JS的加载和执行,等执行结束后,再进行HTML解析,这样是最基本的使用方法,也是比较常见的。
2. async加载
<script async src = "script.js"></script>
异步加载执行,从图中我们可以看到,当浏览器遇到JS代码,就会再开一个线程,先去加载JS,等加载完之后,阻塞HTML解析,执行JS,执行完再回去解析HTML。
也就是说,这种方式,也会阻塞HTML的进行,但是时间可能是在HTML解析,也可能是在解析完成后进行。
3. defer
<script defer src = "script.js"></script>
延迟加载执行,在图中可以看到,当浏览器遇到JS代码,会另开一个线程,加载JS代码,加载完后不会立即执行JS,而会等整个文档解析完毕后,再执行JS代码。之后进行DOM加载。
- 至于到底使用async还是的defer就看具体要求了,但是这两个基本都会提升一定的性能。
回流(Reflow)和重绘(Repiont)
首先介绍一下这两个概念:
-
回流
浏览器根据浏览器可见区域的大小,将所有的“盒子模型”的大小,位置转换为实际的像素值。 -
重绘
当“盒子模型”的一些样式发生变化,这里样式指的是颜色,背景,前景等,不会引起盒子大小和位置的。会发生重绘。
回流一定重绘,但重绘一定会出现回流,回流在重绘之前进行
下面看一下什么时候发生回流和重绘
- 发生回流的时刻
- 添加或删除可见DOM元素(不包括
display: none
的) - 元素尺寸发生变化,包括margin, brder, padding, width, height等
- 位置发生变化
- 元素内容变化,包括
input
框中输入文字 - 浏览器尺寸发生变化(这也是很多网站在我们改变浏览器宽度的时候会卡的原因)
- 设置style属性的值
- 添加或删除可见DOM元素(不包括
- 发生重绘的时刻
- 基本都是CSS样式,颜色、边框样式、背景(包括改变背景图片、背景尺寸)、阴影等
代码优化的方法就是尽量减少回流,或者用重绘来替代回流
- 使用
Transform
替代Top
等 - 使用
visibility
替代display: none
- 复杂的动画可以使用
absolute
,可以让动画的对象脱离文档流,这样,只会让动画的元素产生回流,而页面其他元素不会受动画影响也产生回流。 - GPU加速,这个就不介绍了,毕竟我也不会
大概就写这么多了,以后遇到了再补上