頁面性能優化實踐總結

頁面性能優化

學而不思則惘,思而不學則殆css

前幾天接到一個頁面效果優化的任務,邊作邊查閱了一些關於頁面性能的資料。作完任務以後,抽空寫了一篇總結,梳理一下思路,加深本身的理解。html

1. chrome的timeline

先思考這樣的一個問題:web

什麼叫頁面性能好?如何進行評判?chrome

直觀上講,咱們一般會經過一個頁面流不流暢來判斷一個頁面的性能好很差。可是開發中,總不能這麼隨意吧。canvas

1-1 fps

FPS(frame per second),即一秒之間可以完成多少次從新渲染.segmentfault

網頁動畫的每一幀(frame)都是一次從新渲染,每秒低於24幀的動畫,人眼就能感覺到停頓。通常的網頁動畫,須要達到每秒30幀到60幀的頻率,才能比較流暢瀏覽器

而大多數顯示器的刷新頻率是60Hz,爲了與系統一致,以及節省電力,瀏覽器會自動按照這個頻率,刷新動畫。因此,若是網頁可以作到每秒60幀,就會跟顯示器同步刷新,達到最佳的視覺效果。這意味着,一秒以內進行60次從新渲染,每次從新渲染的時間不能超過16.66ms性能優化

在實際的開發,只要達到30fps就能夠了網絡

1-2 timeline

強大的chrome給咱們提供了一個工具,叫作timeline,在幀模式下,咱們能夠看到代碼的執行狀況frontend

圖片描述

  1. 柱狀'frame':表示渲染過程當中的一幀,也就是瀏覽器爲了渲染單個內容塊而必需要作的工做,包括:執行js,處理事件,修改DOM,更改樣式和佈局,繪製頁面等。幀柱的高度表示了該幀的總耗時,幀柱中的顏色分別對應該幀中包含的不停類型的事件。咱們的目標就是控制其在30fps,即1000ms / 30 = 33.34ms

    • 藍色: 網絡和HTML解析

    • 黃色: JavaScript 腳本運行

    • 紫色: 樣式重計算和佈局 ( Layout , Recaculate Style, Update Layer tree)

    • 綠色: 繪製和合成 ( Paint , Composite Layers)

  2. 30fps和60fps的基準線,能夠直觀地看到頁面每一幀的狀況

  3. 灰色區塊:那些沒有被DevTools感知到的活動

  4. 空白區塊:顯示刷新週期(display refresh cycles)中的空閒時間段??

  5. event :事件,上面能夠看到觸發了什麼的事件,而後執行的語句是哪些,

  6. recalculate style: 從新計算樣式

  7. update layer tree: 【耗時】

  8. composite layers: 【耗時】

  9. paint X n: 【耗時】

2. 頁面渲染的原理和過程

接下來思考這個問題:

什麼是update layer tree,什麼是compsite layers,它們爲何那麼耗時?

要理解update layer treecomposite layers,咱們必須瞭解頁面的渲染原理和過程。

2-1 頁面生成的過程

咱們都知道網頁生成過程,大體能夠分紅五步

  1. HTML代碼轉化爲DOM

  2. CSS代碼轉化成CSSOM(CSS Object Model)

  3. 結合DOM和CSSOM,生成一棵渲染樹(包含每一個節點的視覺信息)

  4. 生成佈局(layout),即將全部渲染樹的全部節點進行平面合成

  5. 將佈局繪製(paint)在屏幕上

那麼,瀏覽器是如何進行渲染的?

2-2 理解圖層

瀏覽器在渲染一個頁面時,會將頁面分爲不少個圖層,圖層有大有小,每一個圖層上有一個或多個節點。瀏覽器實際所作的工做有:

  1. 獲取DOM後分隔爲多個圖層

  2. 對每一個圖層的節點計算樣式結果(recalculate style)

  3. 爲每一個節點生成圖形和位置(layout即reflow和重佈局)

  4. 將每一個節點繪製填充到圖層位圖彙總(paint,repaint)

  5. 圖層做爲紋理加載到GPU

  6. 合併多個圖層到頁面上,生成最終圖像(composite layers)

渲染的過程一般是至關耗時,低效的代碼每每就是觸發過程的layout,paint,composite layers,致使頁面卡頓。

3. 低效的代碼

明白了整個渲染的過程和timeline的操做的含義,那麼能夠思考這樣的一個問題:

什麼樣的代碼會觸發這麼耗時的操做,致使咱們的頁面卡頓?

3-1. 重排和重繪

網頁生成的時候,至少會渲染一次。而咱們須要關注的是用戶訪問過程當中,那些會致使網頁從新渲染的行爲:

  • 修改DOM

  • 修改樣式表

  • 用戶事件(例如鼠標懸停,頁面滾動,輸入框輸入文字等)

從新渲染,就涉及重排重繪

重排(reflow)

即從新生成佈局,重排必然致使重繪,如元素位置的改變,就會觸發重排和重繪。

會觸發重排的的屬性:

  1. 盒子模型相關屬性會觸發重佈局:

    • width

    • height

    • padding

    • margin

    • display

    • border-width

    • border

    • min-height

  2. 定位屬性及浮動也會觸發重佈局:

    • top

    • bottom

    • left

    • right

    • position

    • float

    • clear

  3. 改變節點內部文字結構也會觸發重佈局:

    • text-align

    • overflow-y

    • font-weight

    • overflow

    • font-family

    • line-height

    • vertival-align

    • white-space

    • font-size

重繪(repaint)

即從新繪製,須要注意的是,重繪不必定須要重排,好比改變某個元素的顏色,就只會觸發重繪,而不會觸發重排。

會觸發重繪的屬性

  • color

  • border-style

  • border-radius

  • visibility

  • text-decoration

  • background

  • background-image

  • background-position

  • background-repeat

  • background-size

  • outline-color

  • outline

  • outline-style

  • outline-width

  • box-shadow

手機就算重繪也很慢

重排和重繪會不斷觸發,這是不可避免的,可是它們很是消耗資源,是致使網頁性能低下的根本緣由。

提升網頁性能,就是要下降重排和重繪的頻率和成本,儘可能少觸發從新渲染

大部分瀏覽器經過隊列化修改批量顯示優化重排版過程。然而有些操做會強迫刷新並要求全部計劃改變的部分馬上應用。

3-2 建立圖層

1. 建立圖層有什麼用?

咱們知道瀏覽器layout和paint是在每個圖層上進行的,當有一個元素常常變化,爲了減小這個元素對頁面的影響,咱們能夠爲這個元素建立一個單獨的圖層,來提供頁面的性能。

2. 在何時會建立圖層?

  • 3D或透視變換(perspective transform)CSS屬性(例如translateZ(0)/translate3d(0,0,0))

  • 使用加速視頻解碼的<video>節點

  • 擁有3D(WebGL)上下文或加速的2D上下文的<canvas>節點

  • 混合插件(如Flash)

  • 對本身的opacity作CSS動畫或使用一個動畫webkit變換的元素

  • 擁有加速CSS過濾器的元素

  • 元素有一個包含複合層的後代節點(一個元素擁有一個子元素,該子元素在本身的層裏)

  • 元素有一個z-index較低且包含一個複合層的兄弟元素(換句話說就是該元素在複合層上面渲染)

position爲fixed也會建立圖層,而absolute則不會

3. 建立圖層的弊端

圖層的建立也須要必定的開銷,太多的圖層會消耗過多的內存。這可能致使出現預期以外的行爲,可能會致使潛在的崩潰。

3-3 硬件加速

1. 什麼是硬件加速?

現代瀏覽器大均可以利用GPU來加速頁面渲染。在GPU的衆多特性之中,它能夠存儲必定數量的紋理(一個矩形的像素點集合)而且高效地操做這些紋理(好比進行特定的移動、縮放和旋轉操做)。這些特性在實現一個流暢的動畫時特別有用。瀏覽器不會在動畫的每一幀都繪製一次,而是生成DOM元素的快照,並做爲GPU紋理(也被叫作層)存儲起來。以後瀏覽器只須要告訴GPU去轉換指定的紋理來實現DOM元素的動畫效果。這就叫作GPU合成,也常常被稱做硬件加速

2. 怎麼啓用硬件加速?

CSS animations, transforms 以及 transitions 不會自動開啓GPU加速,而是由瀏覽器的緩慢的軟件渲染引擎來執行。那咱們怎樣才能夠切換到GPU模式呢,不少瀏覽器提供了某些觸發的CSS規則。

  • translate3d(0,0,0)

  • rotate3d(0,0,0,0)

  • scale3d(0,0,0)

  • translateZ(0)【可能】

只須要在css中使用這類屬性,便可開啓硬件加速

3. 硬件加速真的那麼好嗎?

從本人在移動端開發的實踐來看,硬件加速是比較坑的。開啓硬件加速會佔有手機過多的內存而致使手機卡頓(這個時候頁面也確定卡頓了),所以在咱們團隊中,是禁止掉硬件加速的。

具體的原理能夠參考連接5

4. 總結

作完這個任務以後, 才以爲本身真正是在作開發。嚴謹細緻的工匠精神,把控好本身的每一行代碼。面對複雜的問題,一步步分析狀況,查閱資料,不斷地debug,感受提升很多。但願本身繼續加油,也與抽空看這篇文章的你共勉。

5. 參考的文章

  1. http://frontenddev.org/link/the-timeline-panel-of-the-chrome-developer-tools.html#heading-1-2

  2. http://www.javashuo.com/article/p-nkgsludp-ep.html

  3. http://gold.xitu.io/entry/5584c9a2e4b06b8a728fe53d

  4. http://www.javashuo.com/article/p-ektmsbhb-ho.html

  5. http://efe.baidu.com/blog/hardware-accelerated-css-the-nice-vs-the-naughty/

相關文章
相關標籤/搜索