瀏覽器的渲染過程
- 解析HTML,生成DOM樹,解析CSS,生成CSSOM樹
- 將DOM樹和CSSOM樹結合,生成渲染樹(Render Tree)
- Layout(迴流):根據生成的渲染樹,進行迴流(Layout),獲得節點的幾何信息(位置,大小)
- Painting(重繪):根據渲染樹以及迴流獲得的幾何信息,獲得節點的絕對像素
- Display:將像素髮送給GPU,展現在頁面上。
爲了構建渲染樹,瀏覽器主要完成了如下工做:css
- 從DOM樹的根節點開始遍歷每一個可見節點。
- 對於每一個可見的節點,找到CSSOM樹中對應的規則,並應用它們。
- 根據每一個可見節點以及其對應的樣式,組合生成渲染樹。
第一步中,既然說到了要遍歷可見的節點,那麼咱們得先知道,什麼節點是不可見的。不可見的節點包括:css3
- 一些不會渲染輸出的節點,好比script、meta、link等。
- 一些經過css進行隱藏的節點。好比display:none。注意,利用visibility和opacity隱藏的節點,仍是會顯示在渲染樹上的。只有display:none的節點纔不會顯示在渲染樹上。
迴流
前面咱們經過構造渲染樹,咱們將可見DOM節點以及它對應的樣式結合起來,但是咱們還須要計算它們在設備視口(viewport)內的確切位置和大小,這個計算的階段就是迴流。瀏覽器
重繪
最終,咱們經過構造渲染樹和迴流階段,咱們知道了哪些節點是可見的,以及可見節點的樣式和具體的幾何信息(位置、大小),那麼咱們就能夠將渲染樹的每一個節點都轉換爲屏幕上的實際像素,這個階段就叫作重繪節點。緩存
什麼時候發生迴流
迴流這一階段主要是計算節點的位置和幾何信息,那麼當頁面佈局和幾何信息發生變化的時候,就須要迴流。好比如下狀況:ide
- 添加或刪除可見的DOM元素
- 元素的位置發生變化
- 元素的尺寸發生變化(包括外邊距、內邊框、邊框大小、高度和寬度等)
- 內容發生變化,好比文本變化或圖片被另外一個不一樣尺寸的圖片所替代。
- 頁面一開始渲染的時候(這確定避免不了)
- 瀏覽器的窗口尺寸變化(由於迴流是根據視口的大小來計算元素的位置和大小的)
瀏覽器的優化機制
現代的瀏覽器都是很聰明的,因爲每次重排都會形成額外的計算消耗,所以大多數瀏覽器都會經過隊列化修改並批量執行來優化重排過程。瀏覽器會將修改操做放入到隊列裏,直到過了一段時間或者操做達到了一個閾值,才清空隊列。可是!當你獲取佈局信息的操做的時候,會強制隊列刷新,好比當你訪問如下屬性或者使用如下方法:佈局
- offsetTop、offsetLeft、offsetWidth、offsetHeight
- scrollTop、scrollLeft、scrollWidth、scrollHeight
- clientTop、clientLeft、clientWidth、clientHeight
- getComputedStyle()
- getBoundingClientRect
減小重繪與迴流
CSS
- 使用 transform 替代 top
- 使用 visibility 替換 display: none ,由於前者只會引發重繪,後者會引起迴流(改變了佈局
- 避免使用table佈局,可能很小的一個小改動會形成整個 table 的從新佈局。
- 儘量在DOM樹的最末端改變class,迴流是不可避免的,但能夠減小其影響。儘量在DOM樹的最末端改變class,能夠限制了迴流的範圍,使其影響儘量少的節點。
- 避免設置多層內聯樣式,CSS 選擇符從右往左匹配查找,避免節點層級過多。
- 將動畫效果應用到position屬性爲absolute或fixed的元素上,避免影響其餘元素的佈局,這樣只是一個重繪,而不是迴流,同時,控制動畫速度能夠選擇 requestAnimationFrame,詳見探討 requestAnimationFrame。
- 避免使用CSS表達式,可能會引起迴流。
- 將頻繁重繪或者回流的節點設置爲圖層,圖層可以阻止該節點的渲染行爲影響別的節點,例如will-change、video、iframe等標籤,瀏覽器會自動將該節點變爲圖層。
CSS3 硬件加速(GPU加速),使用css3硬件加速,可讓transform、opacity、filters這些動畫不會引發迴流重繪 。優化
JavaScript
- 避免頻繁操做樣式,最好一次性重寫style屬性,或者將樣式列表定義爲class並一次性更改class屬性。
- 避免頻繁操做DOM,建立一個documentFragment,在它上面應用全部DOM操做,最後再把它添加到文檔中。
- 避免頻繁讀取會引起迴流/重繪的屬性,若是確實須要屢次使用,就用一個變量緩存起來。
- 對具備複雜動畫的元素使用絕對定位,使它脫離文檔流,不然會引發父元素及後續元素頻繁迴流。