CSS與瀏覽器的工做原理

此內容均爲借鑑,提煉。編程

現代瀏覽器一般擁有兩個重要的執行線程,這兩個線程相互配合來渲染出頁面:主線程 與 排版線程瀏覽器

主線程:

  1. 運行JavaScript
  2. 計算HTML元素的CSS樣式
  3. 佈局頁面
  4. 把頁面元素繪製成一個或多個位圖
  5. 把這些位圖移交給排版線程

排版線程:

  1. 經過GPU渲染位圖,並顯示在屏幕上
  2. 主線程請求更新位圖的可見部分或即將可見的部分
  3. 判斷出當前頁面處於可見的部分
  4. 判斷出即將經過頁面滾動而可見的部分
  5. 隨着用戶滾動頁面來移動這些部分(可見部分的和即將可見的部分)

GPU:

  1. 排版線程經過GPU把位圖繪製到了屏幕上。
  2. GPU比較擅長於:繪製位圖到屏幕、重複的繪製同一個位圖、在不一樣的位置,以不一樣的旋轉角度,或者不一樣的縮放大小來繪製同一個位圖。
  3. GPU相對慢的地方:將位圖加載到顯存裏。

重排與重繪:

瀏覽器下載完頁面中的全部組件——HTML標記、JavaScript、CSS、圖片以後會解析生成兩個內部數據結構——DOM樹渲染樹數據結構

  1. DOM樹表示頁面結構,渲染樹表示DOM節點如何顯示。
  2. 當DOM的變化影響了元素的幾何屬性(寬或高),瀏覽器須要從新計算元素的幾何屬性,一樣其餘元素的幾何屬性和位置也會所以受到影響。瀏覽器會使渲染樹中受到影響的部分失效,並從新構造渲染樹。這個過程稱爲重排。完成重排後,瀏覽器會從新繪製受影響的部分到屏幕,該過程稱爲重繪。

    tips:並非全部的DOM變化都會影響幾何屬性,好比改變一個元素的背景色並不會影響元素的寬和高,這種狀況下只會發生重繪。佈局

 

引發重排的狀況:

很顯然,每次重排,必然會致使重繪,那麼,重排會在哪些狀況下發生?性能

  1. 添加或者刪除可見的DOM元素
  2. 元素位置改變
  3. 元素尺寸改變
  4. 元素內容改變(例如:一個文本被另外一個不一樣尺寸的圖片替代)
  5. 頁面渲染初始化(沒法避免)
  6. 瀏覽器窗口尺寸改變

這些都是顯而易見的,或許你已經有過這樣的體會,不間斷地改變瀏覽器窗口大小,致使UI反應遲鈍(某些低版本IE下甚至直接掛掉),如今你可能恍然大悟,沒錯,正是一次次的重排重繪致使的!動畫

 

Transition:

在整個Transition的每一幀中,瀏覽器都要去從新佈局,繪製頁面,並把最新的位圖對象加載到GPU。

設計決策:

那麼,是否這就意味這咱們不要去緩動一個元素的高度?非也,一些狀況下,這是你的設計效果的一部分,而且動畫效果能夠很是快的完成。也許動畫的元素是孤立的,不會引發頁面其餘部分進行從新佈局;也許該元素只是單純的進行重繪,瀏覽器能夠快速的完成;也許該元素很小,瀏覽器只需將很小的位圖對象傳遞給GPU。
固然了,在不影響你設計的視覺效果的狀況下,最好去緩動一個性能較好的CSS屬性,如transform,而不是去緩動一個性能較差的CSS屬性,如height。舉例來講,假設你的設計中有一個按鈕,當點擊它的時候會出來一個菜單,試着去緩動菜單的transform屬性來顯示它而不是緩動它的top或height屬性來達到相似的效果。
在動畫上特別快的CSS屬性包括:spa

  1. CSS transform
  2. CSS opacity
  3. CSS filter

總結

重排和重繪是DOM編程中耗能的主要緣由之一,平時涉及DOM編程時能夠參考如下幾點:線程

  1. 儘可能不要在佈局信息改變時作查詢(會致使渲染隊列強制刷新)
  2. 同一個DOM的多個屬性改變能夠寫在一塊兒(減小DOM訪問,同時把強制渲染隊列刷新的風險降爲0)
  3. 若是要批量添加DOM,能夠先讓元素脫離文檔流,操做完後再帶入文檔流,這樣只會觸發一次重排(fragment元素的應用)
  4. 將須要屢次重排的元素,position屬性設爲absolute或fixed,這樣此元素就脫離了文檔流,它的變化不會影響到其餘元素。例若有動畫效果的元素就最好設置爲絕對定位。
相關文章
相關標籤/搜索