css重绘和回流

重绘不一定会引起回流,而回流一定会引起重绘。

重绘

当元素的一部分属性发生改变并不影响它在文档流中的位置(即不会引起布局的变化)时,浏览器会将新样式赋予元素并重新绘制它,这个过程称为重绘。

常见的会引起重绘的属性有:

color                 background                 outline
border-style          background-image           outline-color
border-radius         background-size            outline-style
visibility            background-repeat          outline-width
text-decoration       background-position        box-shadow
回流

当render tree中的一部分或全部元素因为规模尺寸、布局、隐藏等改变而需要浏览器重新计算位置和大小,这个过程称为回流。

常见的会导致回流的操作:

页面初次渲染
浏览器窗口大小发生改变
元素尺寸或位置发生改变
元素字体大小变化
元素内容发生变化(文字数量或图片大小改变等, 如: 用户在input中输入内容)
添加或者删除可见的DOM元素
操作class属性
设置style属性
激活伪类(如::hover)
查询某些属性或调用某些方法

常见的会引起回流的属性:

width            position      overflow
height           float         overflow-y
min-height       left          font-weight
margin           right         font-family
padding          top           white-space
border           bottom        text-align
border-width     clear         vertival-align
display          line-height    

js中常见的会引起回流的属性和方法:

clientWidth、clientHeight、clientTop、clientLeft
offsetWidth、offsetHeight、offsetTop、offsetLeft
scrollWidth、scrollHeight、scrollTop、scrollLeft
scrollIntoView()
scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()

减少页面重绘和回流的方法:

css:

  1. 尽量使用css属性简写:如:用boder代替boder-width,boder-style,boder-color;

  1. 尽量避免用table布局,因为可能很小的一个小改动会造成整个 table 的重新布局;

  1. 避免设置多层内联样式;

  1. 尽可能在DOM树的最末端改变class, 减小回流的范围;

  1. 将动画效果应用到position属性为absolute或fixed的元素上,让它脱离文档流,相当于建了一个新的文档对象,触发回流的是新建的文档对象,否则会引起父元素及后续元素频繁回流;

  1. 避免使用CSS表达式(例如:calc()),因为每次调用都会重新计算和加载页面;

  1. 为动画元素创建新图层,提高动画元素的z-index;

  1. opacity配合图层使用,既不触发重排也不触发重绘;

js:

  1. 避免频繁操作样式,最好一次性重写style属性。或者可以先定义好 css 的 class,然后修改 DOM 的 className;

  1. 避免频繁操作DOM,可以使用文档碎片,将所有添加内容放到容器内,再添加到页面,这样只会触发一次回流和重构。

let fragment=document.createDocumentFragment();
fragment.appendChild(DOM对象);
document.body.appendChild(fragment);

3.可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘;

el.style.display = 'none';
...一些对el的操作
el.style.display = 'block';

4.可以先让元素脱离文档流,操作完之后再重新放回去;

el.style.position='absoulte';
...一些对el的操作
el.style.position='static'

5.如果要用(el.style.)的方式对一个元素设置多个属性,可以使用(el.style.cssText='...')合并成一个;

6.避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,可以用一个变量缓存起来;

7.可以克隆要操作的节点,对克隆之后的节点操作完成后,再替换回去;

const ul = document.getElementById('test');
const clone = ul.cloneNode(true);
...对clone的一些操作
ul.parentNode.replaceChild(clone, ul);

猜你喜欢

转载自blog.csdn.net/qq_35408366/article/details/129142424