頁面的繪製時間(paint time)是每個前端開發都須要關注的的重要指標,它決定了你的頁面流暢程度。而如何去觀察頁面的繪製時間,找到性能瓶頸,能夠藉助Chrome的開發者工具。css
本文主要介紹Chrome渲染分析工具 Rendering。html
如上圖,按F12調出開發者工具,而後按 「ESC」 調出 Rendering 界面。前端
以上5個選項的意思以下:html5
一、Show paint rectangles 顯示繪製矩形ios
二、Show composited layer borders 顯示層的組合邊界(注:藍色的柵格表示的是分塊)css3
三、Show FPS meter 顯示 FPS 幀頻web
四、Enable continuous page repainting 開啓持續繪製模式 並 檢測頁面繪製時間chrome
五、Show potential scroll bottlenecks 顯示潛在的滾動瓶頸。canvas
開啓 顯示繪製矩形 這個選項,能夠看到綠色的框(以前的版本都是紅色的框,如今改綠色了,呵呵),這個綠色的框,表示頁面正在繪製的區域,便是頁面正在渲染,發生繪製操做的區域。 這是用來了解滾動時頁面表現的第一個指示器。瀏覽器
鼠標移到圖片上,能夠發現 css3 動畫的位移,而 css3 動畫的位移致使頁面重繪,重繪的區域便是綠色框住的部分。細心的朋友可能會發現,這個綠色框住的部分,並不只僅就是恰好那個 div 所在的區域,而涉及到周邊的位置。發生這種狀況的緣由,是頁面的重繪是個連帶反應,會影響周邊元素。
開啓這個選項以後,能夠作一些常規的頁面交互操做,如 Slider 切換,拍拍網左側導航 mouse over 時效果,能夠看到頁面效果所影響的範圍。
再好比滾動頁面,拍拍首頁會出現一個返回頂部的按鈕,滾動的時候,會發現返回頂部這個區域在不停的進行重繪,而返回頂部是 position:fixed
定位的。這也解釋了爲何fixed定位是最耗性能的屬性之一
若是這個時候,咱們給頭部的再加個 position:fixed
,而後滾動頁面時,會發現整個頁面都幾乎是綠色框住了,這主要是全部具備 fixed 定位的元素,在頁面繪製時會處於同一個渲染層級上,一頭一尾的 fixed 無疑會致使整個頁面進行重繪,性能很是差。
這裏提到一個渲染層級的概念,webkit 內核的瀏覽器在進行頁面繪製、渲染並最終展現在瀏覽器窗口上,實際上就像是 Photoshop 上的圖層,不一樣的圖層進行疊加最後生成一個圖片的過程。
這個層的詳細介紹,我下一篇文章會詳細介紹,這裏先賣個關子。
回到以前的話題,既然綠色框住的部分表示頁面重繪,那哪些操做會致使重繪呢?
主要有2大類:
一、頁面滾動
二、互動操做
1).Dom 節點被 Javascript 改變,致使 Chrome 從新計算頁面的 layout。
2).動畫不按期更新。
3).用戶交互,如 hover 致使頁面某些元素頁面樣式的變化。
4).調整窗口大小 和 改變字體
5).內容變化,好比用戶在 input 框中輸入文字
6).激活 CSS 僞類,好比 :hover
7).計算 offsetWidth
和 offsetHeight
屬性
8).增長或者移除樣式表
影響重繪的因素不少,這裏列舉了部分在前端開發的過程當中常見的操做:
一、應該儘可能避免重繪,而且儘量的使繪製區域最小,以提高頁面性能。
就上面拍拍網的例子,一頭一尾加上fixed定位致使整個頁面重繪,是不可取的。也許你分析完後之後都不敢用fixed,可是可能在實際工做中這種狀況沒法避免(設計師或產品經理要求)。何東西都有它適用的地方,重要的是做爲前端人員,你應該可以測量並知道你寫的代碼所帶來的性能損耗及所形成的影響。
二、同時避免組合觸發。
如滾動的時候同時執行 hover 效果操做,一個例子(Expensive Scrolls),在滾動的時候同時也有可能觸發頁面模塊的 hover 效果,而 hover 效果用了 box-shadow
、border-radius
等耗性能大的樣式。從而可能致使丟幀現象。
如何去優化:技巧在於滾動時,關閉模塊的 hover 效果,而後設定一個計時器,時間到了再把 hover 打開。意思是咱們保證在滾動時不去執行昂貴的互動事件重繪。當你中止動做一段時間後,咱們再將動畫開啓。
中文可翻譯爲:顯示層的組合邊界。
咱們知道,在頁面最終是由多個「圖層」渲染而成。勾上這個選項,頁面上的「layer(層)」會加上一個黃色的邊框顯示出來,以下圖的天貓首頁頭部所示:
其中:
使用這個工具,能夠查看當前頁面的layer狀況,更好的發現頁面不須要的 layer 將之清除。
在弄明白這個問題以前,咱們須要先了解一個 dom 元素最終是如何轉變爲咱們屏幕上可視的圖像。在概念上講,可簡單的分爲四個步驟:
能夠將這個過程理解爲設計師的 Photoshop 文件。在 ps 源文件裏,一個圖像是由若干個圖層相互疊加而展現出來的。分紅多個圖層的好處就是每一個圖層相對獨立,修改方便,對單個圖層的修改不會影響到頁面上的其餘圖層。
基於 photoshop 的圖層理念來理解web端的層,那麼就很容易理解了。layer 存在的意義在於:用最小的代價來改變某個頁面元素。
咱們能夠將某個 css 動畫或某個js交互效果把它抽離到一個單獨的渲染層,這樣能夠加快渲染的效率。
<video>
元素 <canvas>
元素opacity
作 CSS 動畫或使用一個動畫 webkit 變換的元素在 webkit 內核的瀏覽器中,若是有上述狀況,則會建立一個獨立的 layer。
其中第一點是最經常使用的手段,好比咱們有時候給一個css效果加上 transform: translateZ(0);
,目的就是爲了建立一個獨立的 layer。
另外還有另一個css屬性:will-change
也能實現一樣的效果。
仍是拿photoshop來作比喻,一個ps文件若是有很是多的圖層,那麼這個文件確定是很是大的。那對於web端也是同樣,建立一個新的渲染層,它得消耗額外的內存和管理資源。當在內存資源有限的設備,好比手機上,因爲過多的渲染層來帶的開銷而對頁面渲染性能產生的影響,甚至遠遠超過了它在性能改善上帶來的好處。
舉個栗子,咱們在天貓首頁上加入css:* {-webkit-transform: translateZ(0);}
。 而後使用timeline能夠看到,天貓的渲染耗時很是嚴重。
其影響的是頁面渲染的最後一個環節:Composite Layers。
那麼,一個合理的策略是:當且僅當須要的時候才爲元素建立渲染層。
除了 rendering 裏提供的 show composited layer borders 選項外,還有一個更爲直觀的3d圖像展現:
先選中 timeline 的某一幀,而後選擇下面的 layer 標籤 tab,在右側的區域就能夠看到整個頁面的3d圖層了。
在這個視圖中,你能夠對這一幀中的全部渲染層進行掃描、縮放等操做,同時還能看到每一個渲染層被建立的緣由。
show fps meter能夠理解爲顯示FPS幀頻/幀數。開啓這個選項後,右上角會實時顯示當前頁面的FPS。
先簡單科普一下啥是FPS。FPS全稱叫 Frames Per Second (每秒幀數)。幀數越高,動畫顯示的越流暢。通常的液晶顯示器的刷新頻率也就是 60HZ。也就是說,要想頁面上的交互效果及動畫流暢。那麼FPS穩定在60左右,是最佳的體驗。。據悉 ios上的交互效果都是60FPS呢。
記得之前作Flash遊戲的時候,FPS幀數是遊戲流暢度的一個重要指標。在web端,道理也是同樣。
科普完畢,回到正題。chrome提供的show FPS meter選項,在咱們製做測試頁面交互及動畫性能時很是有用。同時它也提供了當前頁面的GPU佔有率給咱們。
參考:
http://www.html5rocks.com/en/tutorials/speed/unnecessary-paints/
http://www.html5rocks.com/en/tutorials/speed/layers/
https://developer.chrome.com/devtools/docs/rendering-settings