浏览器回流
什么是浏览器回流?
回流是通过JS代码让布局或者几何属性改变,使部分页面或者整个页面更新的过程
浏览器重绘
剩下的是浏览器重绘:比如改变div的visibility, color、background-color等等
浏览器回流会消耗很多,对性能产生影响。相对来说,回流的影响会大于重绘
那问题是如何避免回流?
- CSS方面
- 使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流
- 动画效果应用到position属性为absolute或fixed的元素上,避免影响其他元素的布局
- 控制动画速度可以选择 requestAnimationFrame
- 避免使用CSS表达式 (例如:calc())
- 使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘
- JavaScript方面
- 避免频繁操作style,最好一次性操作完成
- 避免频繁操作DOM、创建一个documentFragment(文档碎片)
- 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来
事件循环
最新的Chrome浏览器包括:
浏览器主进程
,GPU进程
,网络进程
,渲染进程
,和插件进程
等。
需要知道的是:
- JS是单线程的,且是渲染进程的主线程。
- 普通的同步操作,进不到事件循环,直接在主线程中走了。异步操作才会进事件循环(理解成队列即可)。
- 事件循环完成一遍–>渲染UI–>再次事件循环–>再次渲染UI
- 一句话,浏览器不是
傻屌
,会按照你写的渲染出来,也就是不是异步的,直接给你执行了,异步的等异步完成了,给你渲染UI。何况Vue等有虚拟Dom写就完了。 - 事件循环是怎么执行的?
- JS主进程代码执行
- 微任务执行
- 宏任务执行
- 微任务执行
- 宏任务执行
- …循环执行
宏任务主要包含:setTimeout、setInterval、setImmediate、I/O、UI交互事件
微任务主要包含:Promise、process.nextTick、MutaionObserver 等
这块代码执行的时候,会先显示div再隐藏,还是不显示div?
const e1 = doucument.createElement('div');
document.body.appendChild(el);
el.style.display = none;
答案:不显示div。主线程执行完以后,再渲染UI。再事件循环,再渲染UI。
主线程执行完以后,这个屌东西已经是none了,渲染的时候,也不会引起回流。
el.style.display = none;
el.style.display = visible;
el.style.display = none;
el.style.display = visible;
// 当你写这么多代码的时候,浏览器不会傻到挨个给你执行,挨个给你操作Dom。他会看最后结果,再一下子操作Dom