改变一个元素的特性或者修改其内容有时不仅影响该元素,有时候会导致级联的变化,可能影响该元素的子节点、兄弟节点、父节点的改变,所以每次进行修改时,浏览器都必须重新计算这些改变的影响,但是重新计算布局的代价十分昂贵,浏览器必须尽可能少或者延缓布局的工作。但是如果我们编写的代码不能让浏览器有足够的时间和空间来进行优化,强制浏览器执行大量重新计算,就会造成布局抖动,这是造成布局抖动的元凶。因为我们进行一系列连续的读取和写入时,浏览器无法执行优化布局操作。
同时每次修改DOM,浏览器必须在读取任何布局信息之前先重新计算布局,对性能的损耗十分巨大。
避免布局抖动的一种方法就是使用不会导致浏览器重排的方式编写代码:比如批量的读取和写入等。
引起布局抖动的API和属性如下:
接口对象 | 属 性 名 |
Element | clientHeight, clientLeft, clientTop, clientWidth, focus, getBoundingClientRect, getClientRects, innerText, offsetHeight, offsetLeft, offsetParent, offsetTop, offsetTop, offsetWidth, outerText, scrollByLines, scrollByPages, scrollLeft, scrollHeight, scrollIntoView, scrollIntoViewIfNeeded, scrollTop, scrollWidth |
MouseEvent | layerX layerY offsetX offsetY |
Window | getComputedStyle scrollBy scrollTo scroll scrollY |
Frame, Document,Image | height width |
面试题: 什么时候会发生布局抖动?
当我们的代码执行一系列连续的读取和写入DOM时会发生布局抖动,迫使浏览器重新计算布局信息,造成Web 应用程序产生更慢、更少的响应。