1. 程式人生 > 其它 >淺析CSS的效能優化:transform與position區別、硬體加速工作原理及注意事項、強制使用GPU渲染的友好CSS屬性

淺析CSS的效能優化:transform與position區別、硬體加速工作原理及注意事項、強制使用GPU渲染的友好CSS屬性

  在網上看到一個這樣的問題: transform與position:absolute 有什麼區別?查閱資料後發現這道題目其實不簡單,涉及到重排、重繪、硬體加速等網頁優化的知識。

一、問題背景

過去幾年,我們常常會聽說硬體加速給移動端帶來了巨大的體驗提升,但是即使對於很多經驗豐富的開發者來說,恐怕對其背後的工作原理也是模稜兩可,更不要合理地將其運用到網頁的動畫效果中了著作權歸作者所有。
商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
原文: https://www.w3cplus.com/css3/introduction-to-hardware-acceleration-css-animations.html
© w3cplus.com
過去幾年,我們常常會聽說硬體加速給移動端帶來了巨大的體驗提升,但是即使對於很多經驗豐富的開發者來說,恐怕對其背後的工作原理也是模稜兩可,更不要合理地將其運用到網頁的動畫效果中了著作權歸作者所有。
商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
原文: https://www.w3cplus.com/css3/introduction-to-hardware-acceleration-css-animations.html © w3cplus.com

  過去幾年,我們常常會聽說硬體加速給移動端帶來了巨大的體驗提升,但是即使對於很多經驗豐富的開發者來說,恐怕對其背後的工作原理也是模稜兩可,更不要合理地將其運用到網頁的動畫效果中了。

1、position + top/left 的效果

  下面讓我們來看一個動畫效果,在該動畫中包含了幾個堆疊在一起的球並讓它們沿相同路徑移動。最簡單的方式就是實時調整它們的 left 和 top 屬性,使用 css 動畫實現。

<style>
    html,
    body {
        width: 100%;
        height: 100%;
    }
    .ball-running {
        animation: run-around 4s infinite;
        width: 100px;
        height: 100px;
        background-color
: red; position: absolute; } @keyframes run-around { 0%: { top: 0; left: 0; } 25% { top: 0; left: 200px; } 50% { top: 200px; left: 200px; } 75% { top: 200px; left: 0; } } </style> <body> <div class="ball-running"></div> </body>

  在執行的時候,即使是在電腦瀏覽器上也會隱約覺得動畫的執行並不流暢,動畫有些停頓的感覺,更不要提在移動端達到 60fps 的流暢效果了。這是因為top和left的改變會觸發瀏覽器的 reflow 和 repaint ,整個動畫過程都在不斷觸發瀏覽器的重新渲染,這個過程是很影響效能的。

2、transform 的效果

  為了解決這個問題,我們使用 transform 中的 translate() 來替換 top 和 left ,重寫一下這個動畫效果。

<style>
    html,
    body {
        width: 100%;
        height: 100%;
    }
    .ball-running {
        animation: run-around2 4s infinite;
        width: 100px;
        height: 100px;
        background-color: red;
        position: absolute;
    }
    @keyframes run-around2 {
        0%: {
            transform: translate(0, 0);
        }
        25% {
            transform: translate(200px, 0);
        }
        50% {
            transform: translate(200px, 200px);
        }
        75% {
            transform: translate(0, 200px);
        }
    }
</style>
<body>
    <div class="ball-running"></div>
</body>

  這時候會發現整個動畫效果流暢了很多,在動畫移動的過程中也沒有發生repaint和reflow。

  那麼,為什麼 transform 沒有觸發 repaint 呢?原因就是:transform 動畫由GPU控制,支援硬體加速,並不需要軟體方面的渲染。

二、硬體加速工作原理

  瀏覽器接收到頁面文件後,會將文件中的標記語言解析為DOM樹,DOM樹和CSS結合後形成瀏覽器構建頁面的渲染樹,渲染樹中包含了大量的渲染元素,每一個渲染元素會被分到一個圖層中,每個圖層又會被載入到GPU形成渲染紋理,而圖層在GPU中 transform是不會觸發 repaint 的,這一點非常類似3D繪圖功能,最終這些使用transform的圖層都會使用獨立的合成器程序進行處理

  在我們的示例中,CSS transform 建立了一個新的複合圖層,可以被GPU直接用來執行 transform 操作。在chrome開發者工具中開啟“show layer borders”選項後,每個複合圖層就會顯示一條黃色的邊界。示例中的球就處於一個獨立的複合圖層,移動時的變化也是獨立的。

  此時,你也許會問:瀏覽器什麼時候會建立一個獨立的複合圖層呢?事實上一般是在以下幾種情況下:

(1)3D 或者 CSS transform

(2)video或canvas標籤

(3)CSS filters

(4)元素覆蓋時,比如使用了 z-index 屬性

  等一下,上面的示例使用的是 2D transition 而不是 3D 的 transforms 啊?這個說法沒錯,所以在timeline中我們可以看到:動畫開始和結束的時候發生了兩次 repaint 操作。

  3D 和 2D transform 的區別就在於,瀏覽器在頁面渲染前為3D動畫建立獨立的複合圖層,而在執行期間為2D動畫建立。

  動畫開始時,生成新的複合圖層並載入為GPU的紋理用於初始化 repaint,然後由GPU的複合器操縱整個動畫的執行,最後當動畫結束時,再次執行 repaint 操作刪除複合圖層。

三、使用 GPU 渲染元素

1、能觸發GPU渲染的屬性

  並不是所有的CSS屬性都能觸發GPU的硬體加速,實際上只有少數屬性可以,比如下面的這些:

(1)transform

(2)opacity

(3)filter

2、強制使用GPU渲染

  為了避免 2D transform 動畫在開始和結束時發生的 repaint 操作,我們可以硬編碼一些樣式來解決這個問題:

.exam1{
    transform: translateZ(0);
}
.exam2{
    transform: rotateZ(360deg);
}

  這段程式碼的作用就是讓瀏覽器執行 3D transform,瀏覽器通過該樣式建立了一個獨立圖層,圖層中的動畫則有GPU進行預處理並且觸發了硬體加速

3、使用硬體加速需要注意的事項

  使用硬體加速並不是十全十美的事情,比如:

(1)記憶體。如果GPU載入了大量的紋理,那麼很容易就會發生記憶體問題,這一點在移動端瀏覽器上尤為明顯,所以,一定要牢記不要讓頁面的每個元素都使用硬體加速。

(2)使用GPU渲染會影響字型的抗鋸齒效果。這是因為GPU和CPU具有不同的渲染機制,即使最終硬體加速停止了,文字還是會在動畫期間顯示得很模糊。

4、will-change

  瀏覽器還提出了一個 will-change 屬性,該屬性允許開發者告知瀏覽器哪一個屬性即將發生變化,從而為瀏覽器對該屬性進行優化提供了時間。下面是一個使用 will-change 的示例

.exam3{
    will-change: transform;
}

  缺點在於其相容性不大好。

  總結:

1、transform 會使用 GPU 硬體加速,效能更好;position + top/left 會觸發大量的重繪和迴流,效能影響較大。

2、硬體加速的工作原理是建立一個新的複合圖層,然後使用合成執行緒進行渲染。

3、3D 動畫 與 2D 動畫的區別;2D動畫會在動畫開始和動畫結束時觸發2次重新渲染。

4、使用GPU可以優化動畫效果,但是不要濫用,會有記憶體問題。

5、理解強制觸發硬體加速的 transform 技巧,使用對GPU友好的CSS屬性。

英文原文:http://www.sitepoint.com/introduction-to-hardware-acceleration-css-animations/