在瞭解什麼是重構和迴流以前,咱們應該先看看瀏覽器是怎麼渲染的?css
1.處理HTML腳本,生成DOM樹(DOM樹裏包含全部的HTML標籤,包括display:none和js動態添加的元素等)
2.處理CSS腳本,生成CSSOM樹(DOM和CSSOM是獨立的數據結構)
3.將DOM樹和CSSOM樹合併爲渲染樹,render樹中不包含定位和幾何信息。雖然,render樹與dom樹相似但仍是有區別的。render樹中不包含隱藏的節點 (好比display:none的節點,還有head節點),由於這些節點不會用於呈現,並且不會影響呈現的,因此就不會包含到 render tree中。注意 visibility:hidden隱藏的元素仍是會包含到 render tree中的,由於visibility:hidden 會影響佈局(layout),會佔有空間。
4.對render樹中的內容進行佈局,計算每一個節點的幾何外觀
5.將渲染樹中的每一個節點繪製到屏幕中.jquery
重構
:當元素的某些屬性發生變化,這些屬性又隻影響元素的外觀和風格,而不改變元素的佈局、大小好比顏色、背景。此時觸發的瀏覽器行爲稱做重構。迴流
:當元素的佈局、大小規模和顯示方式發生改變時,觸發的瀏覽器行爲叫回流。並且,每一個頁面都會在第一次加載時觸發迴流。
注意:迴流必將引發重繪,而重繪不必定伴隨迴流。同時,迴流對性能的影響要大於重構。瀏覽器
其實任何對render tree中元素的操做都會引發迴流或者重繪,好比:緩存
由於,迴流花銷很大,因此大部分瀏覽器對於迴流都會進行優化,瀏覽器會維護1個隊列,把全部會引發迴流、重繪的操做放入這個隊列,等隊列中的操做到了必定的數量或者到了必定的時間間隔,瀏覽器就會flush隊列,進行一個批處理。這樣就會讓屢次的迴流、重繪變成一次迴流重繪。數據結構
雖然有了瀏覽器的優化,但有些代碼可能會強制瀏覽器提早flush隊列,這樣瀏覽器的優化可能就起不到做用了。當你請求向瀏覽器請求一些 style信息的時候,就會讓瀏覽器flush隊列,好比:dom
當你請求上面的一些屬性的時候,瀏覽器爲了給你最精確的值,須要flush隊列,由於隊列中可能會有影響到這些值的操做。即便你獲取元素的佈局和樣式信息跟最近發生或改變的佈局信息無關,瀏覽器都會強行刷新渲染隊列。佈局
根據上面觸發迴流和重繪的操做,咱們能夠知道只要減小對render tree的操做(合併屢次多DOM和樣式的修改),並減小對一些style信息的請求,就能減小回流、重繪了,儘可能利用好瀏覽器的優化策略。
具體作法有:
1.直接改變className,若是動態改變樣式,則使用cssText(考慮沒有優化的瀏覽器)
2.讓要操做的元素進行」離線處理」,處理完後一塊兒更新:性能
3.不要常常訪問會引發瀏覽器flush隊列的屬性,若是你確實要訪問,利用緩存
4.讓元素脫離動畫流,減小回流的Render樹的規模(即讓動畫的元素脫離文檔流,使用absolute定位等等)。字體