Cara membuat animasi CSS berperforma tinggi

Panduan ini menunjukkan cara membuat animasi CSS berperforma tinggi.

Lihat Mengapa beberapa animasi lambat? untuk mempelajari teori di balik rekomendasi ini.

Kompatibilitas browser

Semua properti CSS yang direkomendasikan panduan ini memiliki dukungan lintas browser yang baik.

Memindahkan elemen

Untuk memindahkan elemen, gunakan nilai kata kunci translate atau rotation dari properti transform.

Misalnya, untuk menggeser item ke tampilan, gunakan translate.

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

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

Item juga dapat diputar, dalam contoh di bawah 360 derajat.

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

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

Mengubah ukuran elemen

Untuk mengubah ukuran elemen, gunakan nilai kata kunci scale dari properti transform.

.animate {
  animation: scale 1.5s both;
}

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

Mengubah visibilitas elemen

Untuk menampilkan atau menyembunyikan elemen, gunakan opacity.

.animate {
  animation: opacity 2.5s both;
}

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

Menghindari properti yang memicu layout atau paint

Sebelum menggunakan properti CSS apa pun untuk animasi (selain transform dan opacity), tentukan dampak properti pada pipeline rendering. Hindari properti apa pun yang memicu layout atau paint kecuali jika benar-benar diperlukan.

Paksa pembuatan lapisan

Seperti yang dijelaskan dalam Mengapa beberapa animasi lambat?, dengan menempatkan elemen pada lapisan baru, elemen tersebut dapat digambar ulang tanpa mengharuskan kita menggambar ulang sisa tata letak.

Browser akan sering kali membuat keputusan yang tepat terkait item mana yang harus ditempatkan di lapisan baru, tetapi Anda dapat memaksa pembuatan lapisan secara manual dengan properti will-change. Seperti namanya, properti ini memberi tahu browser bahwa elemen ini akan diubah dengan cara tertentu.

Di CSS, properti ini dapat diterapkan ke pemilih mana pun:

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

Namun, spesifikasi menunjukkan pendekatan ini hanya boleh dilakukan untuk elemen yang akan selalu berubah. Jika contoh di atas adalah {i>sidebar <i}yang dapat digeser pengguna ke dalam dan ke luar, mungkin itulah masalahnya. Beberapa item di halaman Anda mungkin tidak sering berubah, sehingga sebaiknya terapkan will-change menggunakan JavaScript pada titik di mana perubahan tersebut mungkin akan terjadi. Anda harus memastikan browser memiliki cukup waktu untuk melakukan pengoptimalan yang diperlukan, lalu menghapus properti setelah perubahan berhenti.

Jika memerlukan cara untuk memaksa pembuatan lapisan di salah satu browser langka yang tidak mendukung will-change (kemungkinan besar Internet Explorer pada tahap ini), Anda dapat menetapkan transform: translateZ(0).

Men-debug animasi yang lambat atau tersendat

Chrome DevTools dan Firefox DevTools memiliki banyak alat untuk membantu Anda mengetahui penyebab animasi lambat atau tersendat.

Memeriksa apakah animasi memicu tata letak

Animasi yang menggerakkan elemen menggunakan sesuatu selain transform, kemungkinan akan lambat. Dalam contoh berikut, saya telah mencapai hasil visual yang sama yang menganimasikan top dan left, serta menggunakan transform.

Larangan
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

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

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

Anda dapat mengujinya dalam dua contoh Glitch berikut, dan mempelajari performa menggunakan DevTools.

Chrome DevTools

  1. Buka panel Performance.
  2. Merekam performa runtime saat animasi sedang berlangsung.
  3. Periksa tab Ringkasan.

Jika Anda melihat nilai bukan nol untuk Rendering di tab Ringkasan, itu mungkin berarti bahwa animasi menyebabkan browser melakukan pekerjaan tata letak.

Panel Ringkasan menunjukkan 37 md untuk rendering dan 79 md untuk lukisan.
Contoh animation-with-top-left menyebabkan pekerjaan rendering.
Panel Ringkasan menampilkan nilai nol untuk rendering dan lukisan.
Contoh Animation-with-transform tidak menyebabkan pekerjaan rendering.

DevTools Firefox

Di Firefox DevTools, Waterfall dapat membantu Anda memahami tempat browser menghabiskan waktu.

  1. Buka panel Performance.
  2. Di panel Start Recording Performance saat animasi sedang berlangsung.
  3. Hentikan perekaman dan periksa tab Waterfall.

Jika Anda melihat entri untuk Recalculate Style, browser harus memulai di awal Waterfall rendering.

Memeriksa apakah animasi menurunkan frame

  1. Buka tab Rendering di Chrome DevTools.
  2. Aktifkan kotak centang FPS meter.
  3. Lihat nilainya saat animasi berjalan.

Di bagian atas UI FPS meter, Anda akan melihat label Frames. Di bawahnya, Anda dapat melihat nilai di sepanjang baris 50% 1 (938 m) dropped of 1878. Animasi berperforma tinggi akan memiliki persentase yang tinggi, misalnya 99%. Persentase yang tinggi berarti ada beberapa frame yang dihapus dan animasi akan terlihat halus.

Pengukur fps menunjukkan 50% frame hilang
Contoh animation-with-top-left menyebabkan 50% frame dihapus
Pengukur fps hanya menunjukkan 1% frame yang dilepas
Contoh animasi-with-transform menyebabkan hanya 1% frame dihapus.

Memeriksa apakah animasi memicu paint

Dalam hal melukis, beberapa hal lebih mahal daripada yang lain. Misalnya, apa pun yang melibatkan pemburaman (misalnya, bayangan) akan memakan waktu lebih lama untuk dilukis daripada menggambar kotak merah. Namun, dalam hal CSS, hal ini tidak selalu jelas: background: red; dan box-shadow: 0, 4px, 4px, rgba(0,0,0,0.5); tidak selalu terlihat memiliki karakteristik performa yang sangat berbeda, padahal memang demikian.

DevTools browser dapat membantu Anda mengidentifikasi area mana yang perlu dicat ulang, dan masalah performa yang terkait dengan proses menggambar.

Chrome DevTools

  1. Buka tab Rendering di Chrome DevTools.
  2. Pilih Paint Flashing.
  3. Gerakkan kursor di sekitar layar.
Elemen UI yang ditandai dengan warna hijau untuk menunjukkan bahwa elemen UI akan dicat ulang
Dalam contoh dari Google Maps ini, Anda dapat melihat elemen yang akan dilukis ulang.

Jika Anda melihat seluruh layar berkedip, atau area yang menurut Anda tidak perlu berubah ditandai, Anda dapat melakukan penyelidikan.

Jika Anda perlu mencari tahu apakah properti tertentu menyebabkan masalah performa karena pengecatan, paint profiler di Chrome DevTools dapat membantu.

DevTools Firefox

  1. Buka Settings dan tambahkan tombol Toolbox untuk Toggle paint flashing.
  2. Pada halaman yang ingin diperiksa, aktifkan tombol dan gerakkan mouse atau scroll untuk melihat area yang disorot.

Kesimpulan

Jika memungkinkan, batasi animasi ke opacity dan transform untuk mempertahankan animasi pada tahap komposisi jalur rendering. Gunakan DevTools untuk memeriksa tahap jalur mana yang terpengaruh oleh animasi Anda.

Gunakan paint profiler untuk melihat apakah ada operasi paint yang sangat mahal. Jika Anda menemukan sesuatu, lihat apakah properti CSS yang berbeda akan memberikan tampilan dan nuansa yang sama dengan performa yang lebih baik.

Gunakan properti will-change seperlunya, dan hanya jika Anda mengalami masalah performa.