硬件加速下webview切换闪屏_网页渲染性能优化 —— 性能优化下
博客 有更多精品文章喲。
Composite 的優(yōu)化
終于,我們到了像素管道的末尾。對于這一部分的優(yōu)化策略,我們可以從為什么需要 Composited Layer(Graphics Layer)來入手。這個問題我們在構(gòu)建 Graphics Layer Tree 的時候,已經(jīng)說明過,現(xiàn)在簡單回顧一下:
根據(jù) Composited Layer 的這兩個特點,可以總結(jié)出以下幾點優(yōu)化措施。
使用 transform 和 opacity 屬性來實現(xiàn)動畫
上文我們說過像素管道的 Layout 和 Paint 部分是可以略過,只進(jìn)行 Composite 的。實現(xiàn)這種渲染方式的方法很簡單,就是使用只會觸發(fā) Composite 的 CSS 屬性;目前,滿足這個條件的 CSS 屬性,只有 transform 和 opacity。
使用 transform 和 opacity 需要注意的是:元素必須是 Composited Layer;如果不是,Paint 還是會照常觸發(fā)(Layout 要看情況,一般 transform 會觸發(fā))。來看一個例子:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><style>.div {width: 100px;height: 100px;background-color: #f00;/* will-change: transform; */}</style><title>性能優(yōu)化</title> </head><body><div class="div"></div><script>const div = document.querySelector(".div");const run = () => {div.style.transform = "translate(0, 100px)";};setTimeout(run, 2000);</script> </body> </html>我們將使用 transform 來向下位移,開始我們先不把 div 節(jié)點提升為 Composited Layer;通過下圖可以看到:還是會觸發(fā) Layout 和 Paint 的。
這時,把 div 節(jié)點提升為 Composited Layer,我們發(fā)現(xiàn) Layout 和 Paint 已經(jīng)被略過了,符合我們的預(yù)期。
減少繪制的區(qū)域
如果不能避免繪制,我們就應(yīng)該盡可能減少需要重繪的區(qū)域。例如,頁面頂部有一塊固定區(qū)域,當(dāng)頁面某個其他區(qū)域需要重繪的時候,很可能整塊屏幕都要重繪,這時,固定區(qū)域也會被波及到。像這種情況,我們就可以把需要重繪或者受到影響的區(qū)域提升為 Composited Layer,避免不必要的繪制。
提升成 Composited Layer 的最佳方式是使用 CSS 的 will-change 屬性,它的詳細(xì)說明可以查看 MDN 的文檔。
.element {will-change: transform; }對于不支持的瀏覽器,最簡單的 hack 方法,莫過于使用 3D 變形來提升為 Composited Layer 了。
.element {transform: translateZ(0); }根據(jù)上文所講的例子,我們嘗試使用 will-change 屬性來讓固定區(qū)域避免重繪。
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><style>.div {width: 100px;height: 100px;background-color: #f00;}.header {position: fixed;z-index: 9999;width: 100%;height: 50px;background-color: #ff0;/* will-change: transform; */}</style><title>性能優(yōu)化</title> </head><body><header class="header">固定區(qū)域</header><div class="div">變動區(qū)域</div><script>const div = document.querySelector(".div");const run = () => {div.style.opacity = 0.5;};setTimeout(run, 2000);</script> </body> </html>首先,我們來看下沒有經(jīng)過優(yōu)化的情況;順帶說明查看瀏覽器一幀繪制詳情的過程。
通過上面的圖片(標(biāo)記 7 和標(biāo)記 8)可以看到,固定區(qū)域的確被波及到,并且觸發(fā)重繪了。我們再對比使用 will-change 屬性優(yōu)化過的情況,發(fā)現(xiàn)固定區(qū)域沒有觸發(fā)重繪。
并且,我們也可以通過一幀(標(biāo)記 1)的布局詳情(標(biāo)記 2),查看固定區(qū)域(標(biāo)記 3)是不是提升成 Composited Layer(標(biāo)記 4),才避免的不必要繪制。
合理管理 Composited Layer
提升成 Composited Layer 的確會優(yōu)化性能;但是,要知道創(chuàng)建一個新的 Composited Layer 必須要額外的內(nèi)存和管理,這是非常昂貴的代價。所以,在內(nèi)存資源有限的設(shè)備上,Composited Layer 帶來的性能提升,很可能遠(yuǎn)遠(yuǎn)抵不上創(chuàng)建多個 Composited Layer 的代價。同時,由于每一個 Composited Layer 的位圖都需要上傳到 GPU;所以,不免需要考慮 CPU 和 GPU 之間的帶寬以及用多大內(nèi)存處理 GPU 紋理的問題。
我們通過 1000 個 div 節(jié)點,來對比普通圖層與提升成 Composited Layer 之后的內(nèi)存使用情況??梢园l(fā)現(xiàn)差距還是比較明顯的。
最小化提升
通過上文的說明,我們知道 Composited Layer 并不是越多越好。尤其是,千萬不要通過下面的代碼提升頁面的所有元素,這樣的資源消耗將是異??植赖?。
* {/* or transform: translateZ(0) */will-change: transform; }最小化提升,就是要盡量降低頁面 Composited Layer 的數(shù)量。為了做到這一點,我們可以不把像 will-change 這樣能夠提升節(jié)點為 Composited Layer 的屬性寫在默認(rèn)狀態(tài)中。至于這樣做的原因,我會在下面講解。
看這個例子,我們先把 will-change 屬性寫在默認(rèn)狀態(tài)里;然后,再對比去掉這個屬性后渲染的情況。
.box {width: 100ox;height: 100px;background-color: #f00;will-change: transform;transition: transform 0.3s; } .box:hover {transform: scale(1.5); }使用 will-change 屬性提升的 Composited Layer:
普通圖層:
我們發(fā)現(xiàn)區(qū)別僅在于,動畫的開始和結(jié)束,會觸發(fā)重繪;而動畫運(yùn)行的時候,刪除或使用 will-change 是沒有任何分別的。
我們在構(gòu)建 Graphics Layer Tree 的時候講到過這樣一條理由:
對 opacity、transform、fliter、backdropfilter 應(yīng)用了 animation 或者 transition(需要是 active 的 animation 或者 transition,當(dāng) animation 或者 transition 效果未開始或結(jié)束后,提升的 Composited Layer 會恢復(fù)成普通圖層)。這條理由賜予了我們動態(tài)提升 Composited Layer 的權(quán)利;因此我們應(yīng)該多利用這一點,來減少不必要的 Composited Layer 的數(shù)量。
防止層爆炸
我們在 Graphics Layer Tree 中介紹過層爆炸,它指的是由于重疊而導(dǎo)致的大量額外 Composited Layer 的問題。瀏覽器的層壓縮可以在很大程度上解決這個問題,但是,有很多特殊的情況,會導(dǎo)致 Composited Layer 無法被壓縮;這就很可能產(chǎn)生一些不在我們預(yù)期中的 Composited Layer,也就是說還是會出現(xiàn)大量額外的 Composited Layer。
在層壓縮這一節(jié),我們已經(jīng)給出了使用層壓縮優(yōu)化的例子,這里就不再重復(fù)了。下面再通過解決一個無法被層壓縮的例子,來更為深入的了解如何防止層爆炸。
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><style>.animating {width: 300px;height: 30px;line-height: 30px;background-color: #ff0;will-change: transform;transition: transform 3s;}.animating:hover {transform: translateX(100px);}ul {padding: 0;border: 1px solid #000;}.box {position: relative;display: block;width: auto;background-color: #00f;color: #fff;margin: 5px;overflow: hidden;}.inner {position: relative;margin: 5px;}</style><title>性能優(yōu)化</title> </head><body><div class="animating">動畫</div><ul><li class="box"><p class="inner">提升成合成層</p></li><li class="box"><p class="inner">提升成合成層</p></li><li class="box"><p class="inner">提升成合成層</p></li><li class="box"><p class="inner">提升成合成層</p></li><li class="box"><p class="inner">提升成合成層</p></li></ul> </body> </html>當(dāng)我們的鼠標(biāo)移入 .animating 元素的時候,通過查看 Layers 面板,可以很清晰的看到出現(xiàn)的大量 Composited Layer。
這個例子雖然表面上看起來沒有發(fā)生重疊;但是,因為在運(yùn)行動畫的時候,很可能與其他元素造成重疊,所以 .animating 元素會假設(shè)兄弟元素在一個 Composited Layer 之上。這時,又因為 .box 元素設(shè)置了 overflow: hidden; 導(dǎo)致自己與 .animating 元素有了不同的裁剪容器(Clipping Container),所以就出現(xiàn)了層爆炸的現(xiàn)象。
解決這個問題的辦法也很簡單,就是讓 .animating 元素的 z-index 比其他兄弟元素高。因為 Composited Layer 在普通元素之上,所以也就沒有必要提升普通元素,修正渲染順序了。這里我在順便多說一句,默認(rèn)情況下 Composited Layer 渲染順序的優(yōu)先級是比普通元素高的;但是在普通元素設(shè)置 position: relative; 之后,因為層疊上下文,并且在文檔流后面的原因,所以會比 Composited Layer 的優(yōu)先級高。
.animating {position: relative;z-index: 1;... }當(dāng)然,如果兄弟元素一定要覆蓋在 Composited Layer 之上,那我們也可以把 overflow: hidden; 或者 position: relative; 去掉,來優(yōu)化 Composited Layer 創(chuàng)建的數(shù)量或者直接就不創(chuàng)建 Composited Layer。
參考資料
總結(jié)
本文首先講了渲染需要構(gòu)建的一些樹,然后通過這些樹與像管道各部分的緊密聯(lián)系,整理了一些優(yōu)化措施。例如,我們對合成所進(jìn)行的優(yōu)化措施,就是通過 Graphics Layer Tree 來入手的。
優(yōu)化也不能盲目去做,例如,提升普通圖層為 Composite Layer 來說,使用不當(dāng),反而會造成非常嚴(yán)重的內(nèi)存消耗。應(yīng)當(dāng)善加利用 Google 瀏覽器的調(diào)試控制臺,幫助我們更加詳盡的了解網(wǎng)頁各方面的情況;從而有針對性的優(yōu)化網(wǎng)頁。
文章參考了很多資料,這些資料都在每一節(jié)的末尾給出。它們具有非常大的價值,有一些細(xì)節(jié),本文可能并沒有整理,可以通過查看它們來更為深入的了解。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的硬件加速下webview切换闪屏_网页渲染性能优化 —— 性能优化下的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最近还能买苹果电脑么要买苹果电脑吗
- 下一篇: 神舟笔记本电源管理软件_笔记本电脑长期不