在討論迴流與重繪以前,咱們要知道:瀏覽器
HTML
解析成DOM
,把CSS
解析成CSSOM
,DOM
和CSSOM
合併就產生了Render Tree
。RenderTree
,咱們就知道了全部節點的樣式,而後計算他們在頁面上的大小和位置,最後把節點繪製到頁面上。Render Tree
的計算一般只須要遍歷一次就能夠完成,但table
及其內部元素除外,他們可能須要屢次計算,一般要花3倍於同等元素的時間,這也是爲何要避免使用table
佈局的緣由之一。一句話:迴流必將引發重繪,重繪不必定會引發迴流。緩存
當Render Tree
中部分或所有元素的尺寸、結構、或某些屬性發生改變時,瀏覽器從新渲染部分或所有文檔的過程稱爲迴流。佈局
會致使迴流的操做:性能
DOM
元素CSS
僞類(例如::hover
)一些經常使用且會致使迴流的屬性和方法:字體
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
scrollIntoView()
、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
當頁面中元素樣式的改變並不影響它在文檔流中的位置時(例如:color
、background-color
、visibility
等),瀏覽器會將新樣式賦予給元素並從新繪製它,這個過程稱爲重繪。優化
迴流比重繪的代價要更高。動畫
有時即便僅僅迴流一個單一的元素,它的父元素以及任何跟隨它的元素也會產生迴流。code
現代瀏覽器會對頻繁的迴流或重繪操做進行優化:隊列
瀏覽器會維護一個隊列,把全部引發迴流和重繪的操做放入隊列中,若是隊列中的任務數量或者時間間隔達到一個閾值的,瀏覽器就會將隊列清空,進行一次批處理,這樣能夠把屢次迴流和重繪變成一次。圖片
當你訪問如下屬性或方法時,瀏覽器會馬上清空隊列:
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
width
、height
getComputedStyle()
getBoundingClientRect()
由於隊列中可能會有影響到這些屬性或方法返回值的操做,即便你但願獲取的信息與隊列中操做引起的改變無關,瀏覽器也會強行清空隊列,確保你拿到的值是最精確的。
table
佈局。DOM
樹的最末端改變class
。position
屬性爲absolute
或fixed
的元素上。CSS
表達式(例如:calc()
)。style
屬性,或者將樣式列表定義爲class
並一次性更改class
屬性。DOM
,建立一個documentFragment
,在它上面應用全部DOM操做
,最後再把它添加到文檔中。display: none
,操做結束後再把它顯示出來。由於在display
屬性爲none
的元素上進行的DOM
操做不會引起迴流和重繪。