效能最佳化


效能最佳化

慎重選擇高消耗的樣式

高消耗屬性在繪製前需要瀏覽器進行大量計算:

  • box-shadows

  • border-radius

  • transparency

  • ##transforms
  • CSS filters(效能殺手)
  • 避免過度重排
  • 當重排發生的時候,瀏覽器需要重新計算佈局位置與大小,更多詳情。

    常見的重排元素:
  • width
  • #height
  • padding
  • margin
  • display
  • ##border-width

  • position

  • top

  • left

##right

#bottom
  • font-size
  • #float
  • ##text-align

  • overflow-y

font-weight

overflow

font-family

  • line-height

  • #vertical-align

  • # clear

    white-space
  • #min-height
  • ## 正確使用Display 的屬性## ####Display 屬性會影響頁面的渲染,請合理使用。 ############display: inline後面不應該再使用width、height、margin、padding 以及float;############display: inline-block 後不應該再使用float;############display: block 後不應該再使用vertical-align;############display: table-* 後不應該再使用margin 或float;############不濫用Float######Float在渲染時計算量比較大,盡量減少使用。 ######動畫性能優化######動畫的實現原理,是利用了人眼的「視覺暫留」現象,在短時間內連續播放數幅靜止的畫面,使肉眼因視覺殘象產生錯覺,誤以為畫面在「動」。 ######動畫的基本概念:#############幀:在動畫過程中,每一幅靜止畫面即為一「幀」;########################################################################### ####幀率:即每秒鐘播放的靜止畫面的數量,單位是fps(Frame per second);############幀時長:即每一幅靜止畫面的停留時間,單位一般是ms(毫秒);############跳幀(掉幀/丟幀):在幀率固定的動畫中,某一幀的時長遠高於平均幀時長,導致其後續數幀被擠壓而失去的現象。 ############一般瀏覽器的渲染刷新頻率是 60 fps,所以在網頁當中,幀率如果達到 50-60 fps 的動畫將會相當流暢,讓人感到舒適。 ############如果使用基於javaScript 的動畫,盡量使用requestAnimationFrame. 避免使用setTimeout, setInterval.############避免透過類似jQuery animate()-style改變每個畫面的樣式,使用CSS 聲明動畫會得到更好的瀏覽器最佳化。 ###
  • 使用 translate 取代 absolute 定位就會得到更好的 fps,動畫會更順滑。

多利用硬體能力,如透過3D 變形開啟GPU 加速

一般在Chrome 中,3D或透視變換(perspective transform)CSS屬性和對opacity 進行CSS動畫會建立新的圖層,在硬體加速渲染通道的最佳化下,GPU 完成3D 變形等操作後,將圖層進行複合操作(Compesite Layers),從而避免觸發瀏覽器大面積重繪和重排。

附註:3D 變形會消耗更多的記憶體和功耗。

使用translate3d 右移500px 的動畫流暢度要明顯優於直接使用left:

.ball-1 {
  transition: -webkit-transform .5s ease;
  -webkit-transform: translate3d(0, 0, 0);
}
.ball-1.slidein{
  -webkit-transform: translate3d(500px, 0, 0);
}
.ball-2 {
  transition: left .5s ease; left:0;
}
.ball-2.slidein {
  left:500px;
}

提升CSS 選擇器效能

CSS 選擇器對效能的影響源自於瀏覽器符合選擇器和文件元素時所消耗的時間,所以最佳化選擇器的原則是應盡量避免使用消耗更多匹配時間的選擇器。而在這之前我們需要了解CSS 選擇器匹配的機制, 如子選擇器規則:

#header > a {font-weight:blod;}

我們中的大多數人都是從左到右的閱讀習慣,會習慣性的設定瀏覽器也是從左到右的方式進行匹配規則,推測這條規則的開銷並不高。

我們會假設瀏覽器以這樣的方式運作:尋找 id 為 header 的元素,然後將樣式規則套用到直系子元素中的 a 元素上。我們知道文件中只有一個 id 為 header 的元素,而且它只有幾個 a 元素的子節點,所以這個 CSS 選擇器應該相當有效率。

事實上,卻恰恰相反,CSS 選擇器是從右到左進行規則比對。了解這個機制後,例子中看似高效的選擇器在實際中的匹配開銷是很高的,瀏覽器必須遍歷頁面中所有的 a 元素並且確定其父元素的 id 是否為 header 。

如果把例子的子選擇器改為後代選擇器則會開銷更多,在遍歷頁面中所有 a 元素後還需向其上級遍歷直到根節點。

#header  a {font-weight:blod;}

了解CSS選擇器從右到左匹配的機制後,明白只要當前選擇符的左邊還有其他選擇符,樣式系統就會繼續向左移動,直到找到和規則匹配的選擇符,或因為不符而退出。我們把最右邊選擇符稱之為關鍵選擇器。 ——更多詳情

1、避免使用通用選擇器

/* Not recommended */
.content * {color: red;}

瀏覽器匹配文件中所有的元素後分別向上逐級匹配class 為content 的元素,直到文檔的根節點。因此其匹配開銷是非常大的,所以應避免使用關鍵選擇器是通配選擇器的情況。

2、避免使用標籤或class 選擇器限制id 選擇器

/* Not recommended */
button#backButton {…}
/* Recommended */
#newMenuIcon {…}

3、避免使用標籤限制class 選擇器

/* Not recommended */
treecell.indented {…}
/* Recommended */
.treecell-indented {…}
/* Much to recommended */
.hierarchy-deep {…}

4、避免使用多層標籤選擇器。使用 class 選擇器替換,減少css查找

/* Not recommended */
treeitem[mailfolder="true"] > treerow > treecell {…}
/* Recommended */
.treecell-mailfolder {…}

5、避免使用子選擇器

/* Not recommended */
treehead treerow treecell {…}
/* Recommended */
treehead > treerow > treecell {…}
/* Much to recommended */
.treecell-header {…}

6、使用繼承

/* Not recommended */
#bookmarkMenuItem > .menu-left { list-style-image: url(blah) }
/* Recommended */
#bookmarkMenuItem { list-style-image: url(blah) }

##