標籤:

在移動端使用transform: translate代替top left marg等做位移有好處么 ?

移動端手指滑動是控制元素的transform: translate和控制top left margin 有什麼區別 各有什麼好處 壞處?


其實還會有人告訴你用translate3D更好

top/left是布局類的樣式,這個樣式的變化會導致重排(reflow/relayout),所謂重排即指對這些節點以及受這些節點影響的其它節點,進行CSS計算-&>布局-&>重繪過程,這個過程的前2步是消耗大量資源的

translate是一個繪製樣式(這名詞我瞎編的),這個樣式的變化會導致重繪(repaint),即在屏幕上重新畫一下,不會進行CSS計算和布局這2個性能大戶,所以我們認為translate性能上要明顯好於top/left

translate3D傳說因為走的是3D,所以能得到更完整的GPU加速的支持,在GPU中還有貼圖緩存等手段幫你優化性能,所以更快


結論:有好處

首先如在移動端使用transform: translate代替top left marg等做位移有好處么 ? - 張立理的回答 答案中從reflow和repaint的角度解釋,這是最主要的原因。

另一個原因是現今大部分手機瀏覽器支持對translate3d的元素進行GPU加速,這個我通常簡單的理解為瀏覽器把這個元素單拎出來作為一個繪圖層,這一層交給GPU渲染,完了再回來正常做混合(composite),這樣可以利用GPU加速。於是乎甚至有給元素加上translate3d(0, 0, 0)來「主動觸發」硬體加速這種奇怪的技巧。

隱患是在某些很奇怪的情況下,使用translate3d會造成頁面模糊或者撕裂,這在iPhone4/4S/5的時候我遇到過很多,成因的話我覺得並不是我擼多了,也許還是那時候的iOS的硬體加速有BUG吧。但這種情況已經很久沒碰到過了。


首先,瀏覽器繪製 DOM 的過程是這樣子的:

  1. 獲取 DOM 並將其分割為多個層(layer)
  2. 將每個層獨立地繪製進點陣圖(bitmap)中
  3. 將層作為紋理(texture)上傳至 GPU
  4. 複合(composite)多個層來生成最終的屏幕圖像。

left/top/margin 之類的屬性會影響到元素在文檔中的布局,當對布局(layout)進行動畫時,該元素的布局改變可能會影響到其他元素在文檔中的位置,就導致了所有被影響到的元素都要進行重新布局[1],瀏覽器需要為整個層進行重繪並重新上傳到 GPU,造成了極大的性能開銷。

transform 屬於合成屬性(composite property),對合成屬性進行 transition/animation 動畫將會創建一個合成層(composite layer),這使得被動畫元素在一個獨立的層中進行動畫。通常情況下,瀏覽器會將一個層的內容先繪製進一個點陣圖中,然後再作為紋理(texture)上傳到 GPU,只要該層的內容不發生改變,就沒必要進行重繪(repaint),瀏覽器會通過重新複合(recomposite)來形成一個新的幀[2]。

層創立的條件如下:

  • 3D 或透視變換 CSS 屬性
  • 使用加速視頻解碼的 & 元素
  • 擁有 3D (WebGL) 上下文或加速的 2D 上下文的 & 元素
  • 複合插件(如 Flash)
  • 進行 opacity/transform 動畫的元素
  • 擁有加速 CSS filters 的元素
  • 元素有一個包含複合層的後代節點(換句話說,就是一個元素擁有一個子元素,該子元素在自己的層里)
  • 元素有一個 z-index 較低且包含一個複合層的兄弟元素(換句話說就是該元素在複合層上面渲染)

總結:

  1. 對布局屬性進行動畫,瀏覽器需要為每一幀進行重繪並上傳到 GPU 中
  2. 對合成屬性進行動畫,瀏覽器會為元素創建一個獨立的複合層,當元素內容沒有發生改變,該層就不會被重繪,瀏覽器會通過重新複合來創建動畫幀

參考資料(需翻牆):

  1. High Performance Animations

  2. Accelerated Rendering in Chrome: The Layer Model


你做個性能檢測就知道有什麼好處了


性能更好,移動端大量使用,用top,left一般是為了在pc上兼容老的瀏覽器


translate的一個不好的地方是(特定使用場景下)過渡使用,比如在web game中,如果粒子數目巨大,會導致創建過多的layers,導致較大的layers組合時間消耗。所以實際測試總是需要的。

另外對於絕對定位元素修改top/left,按理不應該出現重排,因其不影響正常文檔流,但在Chrome46中實測結果是仍然會有幾毫秒的layout(整個document對象),也許是webkit渲染引擎未對此做硬編碼處理,解析只要position改變就重新排列。


可以看看以下鏈接:

Mars/css-property-animation-performance.md at master · AlloyTeam/Mars · GitHub


推薦閱讀:

手淘的Flexible方案能使用雪碧圖嗎?
極樂技術周報(第四十一期)
前端性能優化
當我們在談論前端加密時,我們在談些什麼

TAG:前端開發 |