如何建立高效能 CSS 動畫

本指南說明如何建立高效能的 CSS 動畫。

請參閱「為什麼有些動畫速度較慢?」一節, 背後的理論

瀏覽器相容性

本指南建議的所有 CSS 屬性均具備良好的跨瀏覽器功能 聯絡。

transform

瀏覽器支援

  • Chrome:36.
  • Edge:12.
  • Firefox:16.
  • Safari:9.

資料來源

opacity

瀏覽器支援

  • Chrome:1.
  • Edge:12.
  • Firefox:1.
  • Safari:2.

資料來源

will-change

瀏覽器支援

  • Chrome:36.
  • Edge:79,
  • Firefox:36。
  • Safari:9.1。

資料來源

移動元素

如要移動元素,請使用 translaterotation 關鍵字值 transform 資源。

舉例來說,如要將項目滑動到檢視畫面中,請使用 translate

.animate {
  animation: slide-in 0.7s both;
}

@keyframes slide-in {
  0% {
    transform: translateY(-1000px);
  }
  100% {
    transform: translateY(0);
  }
}

使用 rotate 旋轉元素。以下範例旋轉元素 360 度。

.animate {
  animation: rotate 0.7s ease-in-out both;
}

@keyframes rotate {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

調整元素大小

如要調整元素大小,請使用 scale 關鍵字值 transform 資源。

.animate {
  animation: scale 1.5s both;
}

@keyframes scale {
  50% {
    transform: scale(0.5);
  }
  100% {
    transform: scale(1);
  }
}

變更元素的顯示設定

如要顯示或隱藏元素,請使用 opacity

.animate {
  animation: opacity 2.5s both;
}

@keyframes opacity {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

避免使用會觸發版面配置或繪製的屬性

針對動畫使用任何 CSS 屬性 (transformopacity 除外) 之前, 判斷屬性對轉譯管道的影響。 除非必要,否則請避免使用任何會觸發版面配置或繪製的屬性。

強制建立圖層

如「為什麼有些動畫速度較慢?」一文所述。 將元素放置在新的圖層上,瀏覽器不需自行繪製元素即可 就會重新繪製版面配置的其餘部分

瀏覽器通常可以做出明智的判斷,決定哪些項目應該放在 但您可以使用 will-change 資源。 顧名思義,這個屬性會告知瀏覽器此元素將 帶有某種改變

在 CSS 中,您可以將 will-change 套用至任何選取器:

body > .sidebar {
  will-change: transform;
}

不過,規格 表示您應該只對 變更。舉例來說,假如使用者能在側欄中滑入並 。對於不常變更的元素,我們建議 在可能會發生變更的情況下,will-change 使用 JavaScript。請務必 讓瀏覽器有足夠的時間執行必要的最佳化作業,並移除 屬性。

如何在不支援 will-change 的瀏覽器上強制建立圖層 (最有可能是 Internet Explorer),您可以設定 transform: translateZ(0)

針對緩慢或故障的動畫進行偵錯

Chrome 開發人員工具和 Firefox 開發人員工具 為何動畫速度緩慢或出現異常

檢查動畫是否會觸發版面配置

使用 transform 以外內容移動元素的動畫 但處理速度可能較慢以下範例使用 transform 比較動畫 使用 topleft 轉換為動畫

錯誤做法
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     top: calc(90vh - 160px);
     left: calc(90vw - 200px);
  }
}
正確做法
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     transform: translate(calc(90vw - 200px), calc(90vh - 160px));
  }
}

您可以使用以下兩個 Glitch 範例進行測試 以及使用開發人員工具探索效能

Chrome 開發人員工具

  1. 開啟「Performance」面板。
  2. 記錄執行階段效能 同時載入動畫
  3. 檢查「Summary」分頁。

如果您在「Summary」分頁中看到「Rendering」的值不是零,可能 動畫是瀏覽器讓瀏覽器可以正常運作。

「Summary」面板會顯示 37 毫秒的算繪和 79 毫秒的繪製作業。
animation-with-top-left 範例會造成轉譯工作
,瞭解如何調查及移除這項存取權。
「Summary」面板會顯示零的算繪和繪製值。
使用轉場效果的動畫 不會導致轉譯工作

Firefox 開發人員工具

在 Firefox 開發人員工具中,Waterfall 可協助你瞭解瀏覽器使用時間的頁面。

  1. 開啟「Performance」面板。
  2. 在播放動畫時開始記錄效能。
  3. 停止錄製並檢查「Waterfall」分頁。

如果看到「Recalculate Style」(重新計算樣式) 的項目, 這表示瀏覽器必須回到 算繪刊登序列 轉譯動畫。

檢查是否有掉的影格

  1. 在 Chrome 開發人員工具中開啟「Rendering」分頁
  2. 勾選「FPS meter」核取方塊。
  3. 在播放動畫時觀察值。

留意「FPS meter」UI 頂端的「Frames」標籤。 這會顯示 50% 1 (938 m) dropped of 1878 之類的值。高效能 動畫的播放百分比很高 (例如 99%),表示影格數不多 讓動畫看起來更流暢

fps 計量器顯示已捨棄的 50% 影格
animation-with-top-left 這會導致 50% 的影格遺失
fps 計量器只會顯示已捨棄的 1% 影格
使用轉場效果的動畫 我們只會捨棄 1% 的影格。

檢查動畫是否觸發繪製動作

某些屬性比其他屬性更昂貴。適用對象 舉例來說,任何需要模糊處理的部分 (例如陰影) 都會拉長 不需要繪製紅色方塊有時在 不過,您可以透過瀏覽器開發人員工具 判斷在 和其他繪畫相關的效能問題。

Chrome 開發人員工具

  1. 在 Chrome 開發人員工具中開啟「Rendering」分頁
  2. 選取「Paint Flashing」
  3. 在畫面上移動指標。
,瞭解如何調查及移除這項存取權。
以綠色醒目顯示的 UI 元素,表示即將重新繪製
在這個 Google 地圖範例中,你可以看到元素重新繪製了。

如果發現整個畫面閃爍,或是你認為不合適的區域 需要改變,進一步調查。

若您需要判斷特定資源是否 繪畫相關的效能問題、繪圖分析器

Firefox 開發人員工具

  1. 開啟「Settings」(設定) 並新增 [Toolbox] (工具箱) 按鈕 切換閃光燈閃爍功能
  2. 在要檢查的頁面上,將按鈕切換為開啟,然後移動滑鼠或 請捲動畫面來查看醒目顯示的區域。

結論

請盡可能將動畫限制為 opacitytransform, 產生動畫。使用開發人員工具進行確認 路徑的哪個階段會受到動畫影響

使用繪圖分析器,查看任何繪製作業是否特別重要 。如果發現任何內容,請確認其他 CSS 資源是否提供 採用相同的外觀和風格,廣告成效更優異。

請謹慎使用 will-change 屬性,且只在遇到效能問題時才使用。