Performance & Best Practices — Web Animation

Animation Performance & Best Practices Animasi yang lambat atau jank lebih buruk daripada tidak ada animasi sama sekali. Memahami bagaimana browser merender ani

Animation Performance & Best Practices

Animasi yang lambat atau jank lebih buruk daripada tidak ada animasi sama sekali. Memahami bagaimana browser merender animasi akan membantumu membuat animasi yang smooth di semua device.

Rendering Pipeline Browser

Setiap frame yang browser render melewati pipeline:

JavaScript → Style → Layout → Paint → Composite
  1. JavaScript — kalkulasi dan perubahan DOM
  2. Style — hitung CSS yang berlaku
  3. Layout — hitung posisi dan ukuran setiap elemen
  4. Paint — gambar piksel (warna, shadow, text)
  5. Composite — gabungkan layer dan tampilkan ke layar

Repaint vs Reflow

Reflow (layout) terjadi saat kamu mengubah properti yang mempengaruhi posisi atau ukuran elemen:

/* TRIGGER REFLOW — mahal! */
width, height, margin, padding,
top, left, right, bottom,
font-size, display, position, float

Repaint terjadi saat kamu mengubah properti visual tanpa mengubah layout:

/* TRIGGER REPAINT — cukup mahal */
background-color, color, visibility,
border-color, box-shadow, outline

Compositor-only Properties

Properti yang hanya membutuhkan compositing — paling murah dan paling smooth:

/* COMPOSITOR ONLY — sangat murah! */
transform    /* translate, rotate, scale */
opacity

/* Selalu prioritaskan dua properti ini untuk animasi */
/* BURUK — trigger reflow setiap frame */
.animate-bad {
  transition: left 0.3s, top 0.3s, width 0.3s;
}
.animate-bad:hover {
  left: 100px;
  top: 50px;
  width: 200px;
}

/* BAIK — hanya compositor, no reflow */
.animate-good {
  transition: transform 0.3s;
}
.animate-good:hover {
  transform: translate(100px, 50px) scale(1.2);
}

will-change — Gunakan dengan Hati-hati

/* BENAR — set sebelum animasi, hapus setelahnya */
.card:hover {
  will-change: transform;
}

/* SALAH — jangan set pada semua elemen */
* { will-change: transform, opacity; }

/* SALAH — terlalu banyak properti */
.element {
  will-change: transform, opacity, top, left, width, height;
}

Setiap elemen dengan will-change mendapat layer terpisah di GPU. Terlalu banyak layer = boros memori dan justru bisa memperlambat.

prefers-reduced-motion

Wajib hormati preferensi user yang sensitif terhadap gerakan:

/* Matikan animasi untuk user yang memilih reduced motion */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
// Cek di JavaScript
const prefersReducedMotion = window.matchMedia(
  '(prefers-reduced-motion: reduce)'
).matches;

if (prefersReducedMotion) {
  // Skip animasi atau gunakan alternatif yang lebih subtle
  gsap.globalTimeline.timeScale(100); // instant
}

Performance Debugging Tools

Chrome DevTools Performance Tab

  1. Buka DevTools → Performance tab
  2. Klik record, lakukan interaksi, stop record
  3. Lihat frame rate (harus konsisten 60fps)
  4. Cari long tasks (blok merah) yang menyebabkan jank

DevTools Rendering Tab

  1. Buka DevTools → tekan Ctrl+Shift+P → ketik "rendering"
  2. Aktifkan Paint flashing — area yang di-repaint akan flash hijau
  3. Aktifkan Layout shift regions — area yang reflow akan flash biru
  4. Aktifkan Layer borders — lihat compositor layers

Best Practices Checklist

Duration & Timing

What to Animate

Accessibility

Mobile Considerations

Contoh: Optimized Fade-in on Scroll

// Optimized IntersectionObserver + CSS transition
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add('visible');
      observer.unobserve(entry.target);
    }
  });
}, { threshold: 0.1 });
.fade-in {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.5s ease-out, transform 0.5s ease-out;
}

.fade-in.visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .fade-in {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

Animasi yang baik adalah animasi yang user rasakan tapi tidak sadari. Jika user memperhatikan animasinya, mungkin animasinya terlalu berlebihan atau terlalu lambat.