摘要:無線頁面本就分秒必爭,更不用說當我們在無線頁面中使用動畫的時候。頁面中元素的布局是相對的,因此一個元素的布局發生變化,會聯動地引發其他元素的布局發生變化。它通知瀏覽器在頁面重繪前執行你的回調函數。
無線頁面本就分秒必爭,更不用說當我們在無線頁面中使用動畫的時候。不管是css動畫還是canvas動畫,我們都需要時刻小心著,并且有必要掌握頁面性能的基本分析方法。
既然我們的目標是優化,那么就與瀏覽器的一些渲染和執行機制有關,更好的迎合瀏覽器的行為方式,才可以讓我們的動畫流暢而優美。
沒錯,瀏覽器是老大,全聽它的。
一、設備刷新率(幀率)我們想讓頁面變快,想讓動畫流暢,我們需要先了解一下是什么在影響著我們的感知。
頁面運行在設備的瀏覽器中,現在市面上的移動設備的刷新頻率大多是60次/秒(幀率)。所以給瀏覽器渲染每一幀的畫面的時間應該是(1s/60=16.67ms)。
但實際上,瀏覽器并不是把功夫全花在為我們渲染頁面上,他還需要做一些額外的工作,比如渲染隊列的管理和不同線程的切換等等。所以,單純的瀏覽器渲染工作留給我們的時間大約也就是10ms左右,當我們在每一幀所做的渲染操作大于這個時間的時候,比較直觀的表現就是頁面卡頓,動畫卡頓。
當我們使用css animation完成動畫時,這一點看起來沒有那么重要,因為瀏覽器會為我們handle一些事情。但是當我們需要使用js比如canvas來實現流暢的逐幀動畫時,需要牢記這個有限的時間,它很重要。
二、瀏覽器的頁面渲染流水線我們的代碼是如何一步步的渲染成頁面的呢?
JavaScript。一般來說,我們使用JavaScript來實現一些頁面邏輯,但偶爾我們也可能會使用JavaScript來實現一些視覺變化的效果。比如用jQuery的animate函數做一個動畫、或者往頁面里添加一些DOM元素等。當然,現在更可能的是使用CSS Animations, Transitions和Web Animation API。
計算樣式(Style)。這個過程是通過樣式文件中的CSS選擇器,對每個DOM元素匹配對應的CSS樣式。
布局(Layout)。上一步確定了每個DOM元素的樣式規則,這一步就是具體計算每個DOM元素最終在屏幕上顯示的大小和位置。web頁面中元素的布局是相對的,因此一個元素的布局發生變化,會聯動地引發其他元素的布局發生變化。因此對于瀏覽器來說,布局過程是經常發生的。
繪制(Paint)。繪制,本質上就是填充像素的過程。包括繪制文字、顏色、圖像、邊框和陰影等,也就是一個DOM元素所有的可視效果。一般來說,這個繪制過程是在多個層上完成的。
渲染層合并(Composite)。由上一步可知,對頁面中DOM元素的繪制是在多個層上進行的。在每個層上完成繪制過程之后,瀏覽器會將所有層按照合理的順序合并成一個圖層,然后顯示在屏幕上。對于有位置重疊的元素的頁面,這個過程尤其重要,因為一旦圖層的合并順序出錯,將會導致元素顯示異常。
看起來每個頁面都會經歷這樣的幾個過程,然而我們其實可以使用一些技巧,幫助瀏覽器跳過某些步驟,而縮短他的工作時間。
1.五個步驟都消耗了時間
當我們在js中改變了某個DOM元素的layout時,那么瀏覽器就會檢查頁面中的哪些元素需要重新布局,然后對頁面激發一個reflow過程以完成頁面的重新布局。被reflow的元素,接下來就一定會再次經過Paint和Composite這兩個過程,以渲染出最新的頁面。
2.跳過layout這一步
當我們只修改了一個DOM元素的paint only屬性的時候,比如background-image/color/box-shadow等。這個時候不會觸發layout,瀏覽器在完成樣式的計算之后就會跳過layout的過程,就只Paint和Composite了。
3.跳過layout和paint這兩步
如果你修改一個非樣式且非繪制的CSS屬性,那么瀏覽器會在完成樣式計算之后,跳過布局和繪制的過程,直接Composite。
我們嘗試下使用transform動畫來盡可能的達到這種效果。
三、使用transform實現動畫我們可能經常需要做一些動畫,比如在做某些揭秘或者新手引導的效果時,會需要做一些將內容移入移出的操作。
當然可能第一個想到的就是 css transition 只要過渡一下 left 值或者 bottom 的值就可以了。效果或許很快就會實現,但是當我們在一個頁面頻繁的做著這樣的移入移出操作時,細心地我們放在手機中(6P)看一看,動畫并不會很流暢,尤其是在某些低端機型上。
我們換用 transform 來實現相同的效果:
1 transition: left 2s ease-in-out; ---> transition: transform 2s ease-in-out; 2 left: xxx; ---> transform: translate3d(xxx, yyy, zzz);
原因在于:
簡單的說頁面的繪制并不是在單層的畫面里完成的,這其中有渲染層合成層等概念。對 opacity 和 transform 應用了 CSS 動畫的渲染層、有 3D 或者 perspective transform 的 CSS 屬性的渲染層等滿足一些條件的渲染層被稱為合成層;
合成層有自己的渲染上下文,并且交由 GPU 處理,比 CPU 要快;
當頁面需要重繪時,合成層的元素只會重繪自己層內的元素,而非整個頁面;
優化過后再放在設備里查看,可以感受到效果明顯的提升。其實這里就做到了上面提到的,節省了layout和paint。
現在css的動畫越來越好用,也能滿足越來越多的需求。但在某些復雜的需求中我們可能還是要求助于js。
比如說我這里實現的一個半圓的動畫:半圓progress。看起來使用css動畫就完全可以滿足我的需求,但是當需求變化的時候,我們也只能擁抱變化了。
使用requestAnimationFrame
圓弧progress這里用canvas實現了自定義弧度圓弧的增長動畫。
這里我們借助這個動畫效果看一下是如何使用canvas和requestAnimationFrame來實現流暢的逐幀動畫的。
window.requestAnimationFrame 是一個專門為動畫而生的 web API 。它通知瀏覽器在頁面重繪前執行你的回調函數。通常來說被調用的頻率是每秒60次。
假設我們的頁面上有一個動畫效果,如果我們想保證每一幀的順利繪制,那么我們就需要requestAnimationFrame來保證我們的繪制時機了。
很多框架和示例代碼都是用setTimeout或setInterval來實現頁面中的動畫效果,比如jQuery中的animation。這種實現方式的問題是,你在setTimeout或setInterval中指定的回調函數的執行時機是無法保證的。它將在這一幀動畫的_某個時間點_被執行,很可能是在幀結束的時候。這就意味這我們可能失去這一幀的信息。
requestAnimationFrame的其他高能用法
根據requestAnimationFrame的特性,其實我們還可以在很多別的想不到的地方來一顯身手。
動畫:也是它的主要用途,它將我們動畫的執行時機和執行頻率交由瀏覽器決定,以得到更好的性能;
函數節流:requestAnimationFrame 的執行頻率(一幀)是16.67ms,利用這一個特征就可以做到函數節流,避免高頻事件在一幀內做多余的無用功的函數執行,例:
1 var $box = $("#J_Test"), 2 $point = $box.find("b"); 3 $box.on("mouseenter",function(e){ 4 requestAnimationFrame(function(){ 5 $point.css({ 6 top : e.pageY, 7 left : e.pageX 8 }) 9 }); 11 });
分幀初始化:同樣利用一幀的執行時間將模塊的初始化或渲染函數分散到不同的幀中來執行,這樣每個模塊都有16.67ms的執行時間,而不是一股腦的堆在那里等著執行;
1 var rAF = window.requestAnimationFrame || window.webkitRequestAnimationFrame || 2 function(c) { 3 setTimeout(c, 1 / 60 * 1000); 4 }; 5 6 function render() { 7 self.$container.html(itemHtml); 8 self.$container.find(".J_LazyLoad").lazyload(); 9 } 10 11 rAF(render);五、分析你的無線頁面
我們還是借助這個例子,圓弧progress 簡單的看下如何分析無線頁面的性能。
這里的實現思路是這樣的:
確定圓弧的起始弧度(0.75PI)和終止弧度(根據當前分值占上限分值的比例計算,最大為2.25PI);
隨著時間的增長逐幀繪制終點位置 requestAnimationFrame(draw);
根據每一幀的終點位置的 cos 和 sin 值得到跟隨的圓圈坐標并繪制;
但當然,實現完成只是走了第一步,我們來借助Chrome Timeline來分析一下這個簡單的頁面。
看一下幀率,在進度動畫進行的時候,看起來幀率不錯,沒有產生掉幀的現象,說明每一幀的耗時都還ok,我的動畫基本不會卡頓;
在函數的執行和調用那一欄中,可能有問題的部分右上角會被標紅,還可以查看可能存在問題的細節;這里提示我頁面強制重排了,仔細觀察下面的 Bottom-up tab 中可以定位到具體的代碼。
使用Timeline就可以看到頁面的幾種指標,幀率,js執行等等。就可以針對出現問題的幀下手優化。
在分析頁面性能的時候,嚴重推薦閱讀:[https://developer.chrome.com/devtools/docs/timeline] .timeline的詳細使用說明,它真的很強大,能幫助我們分析到頁面的各個方面的問題。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79307.html
摘要:特點是與年月推出的一個開源的,移動端頁面加速解決方案。僅運行加速動畫移動端動畫優化主要方案。緩存緩存頁面,加速文檔請求相應。參考資料中文文檔如何提升性能,來自的移動頁面優化方案關于谷歌的,你需要知道這些瀏覽器渲染頁面過程與頁面優化 showImg(https://segmentfault.com/img/bVbfUVe?w=394&h=219); AMP在國內應該很少有人接觸得到,今天...
摘要:道阻且長啊前端面試總結前端面試筆試面試騰訊一面瀏覽器工作原理瀏覽器的主要組件包括用戶界面包括地址欄后退前進按鈕書簽目錄瀏覽器引擎用來查詢及操作渲染引擎的接口渲染引擎渲染界面和是基于兩種渲染引擎構建的,使用自主研發的渲染引擎,和都使用網絡用來 道阻且長啊TAT(前端面試總結) 前端 面試 筆試 面試 騰訊一面 1.瀏覽器工作原理 瀏覽器的主要組件包括: 用戶界面- 包括地址欄、后退/前...
摘要:道阻且長啊前端面試總結前端面試筆試面試騰訊一面瀏覽器工作原理瀏覽器的主要組件包括用戶界面包括地址欄后退前進按鈕書簽目錄瀏覽器引擎用來查詢及操作渲染引擎的接口渲染引擎渲染界面和是基于兩種渲染引擎構建的,使用自主研發的渲染引擎,和都使用網絡用來 道阻且長啊TAT(前端面試總結) 前端 面試 筆試 面試 騰訊一面 1.瀏覽器工作原理 瀏覽器的主要組件包括: 用戶界面- 包括地址欄、后退/前...
閱讀 3233·2021-09-07 10:10
閱讀 3579·2019-08-30 15:44
閱讀 2578·2019-08-30 15:44
閱讀 2982·2019-08-29 15:11
閱讀 2219·2019-08-28 18:26
閱讀 2745·2019-08-26 12:21
閱讀 1113·2019-08-23 16:12
閱讀 3010·2019-08-23 14:57