翻译过来就是:在执行JavaScript时发生强制回流。
首先了解一下页面如何呈现?
-
HTML文档加载后生成DOM树(包括display:none的元素) -
在DOM树的基础上配合CSS样式结构体生成render树(不包括display:none、head节点, 包括visibility: hidden节点),即页面中的占位确定了 -
最后绘制页面(也叫渲染),不会改变页面布局的一些属性:color、背景色等
再了解一下什么是回流和重绘?
-
回流:render树中部分或全部元素的尺寸、布局、隐藏(内容、结构、位置)改变引起的,每个页面至少有一次回流(即初始构建页面时) -
重绘:更新页面元素的属性引起的,如颜色、透明度等不会改变页面布局而需要重新渲染的
所以,可以看出,引起回流的情况可以有以下:
- DOM操作(对元素的增删改、顺序变化等)
- 内容变化,包括表单区域内的文本变化
- CSS属性的改变或者重新计算
- 增删样式表内容
- 修改class属性
- 浏览器窗口变化(滚动或回放)
- 伪类样式激活(:hover等)
使用场景: 有一个页面需要展示许多测试项,每个测试项都有几个图表,在这里图表使用的是Echarts并做了简单封装。测试项多的时候,可能需要展示上达几十个图。
基于Echarts的封装组件中有一个props为是否开启自适应(resize),实现如下:
window.addEventListener('resize', resizeHandler)
const resizeHandler = function() {
setTimeout(() => {
chart.value.resize()
}, 500);
}
-
开启自适应的话意味着浏览器同时对几十个图进行监听,一旦浏览器窗口变化,这几十个图表都要进行自适应,出现了回流。
-
另外,动画效果也会导致回流,没有多大必要的时候,在这几十个图表的配置项中将animation设置为false。