Topik wawancara representatif

Wawancara Frontend: Bagaimana Anda membangun animasi berbasis scroll (scroll-driven animation) dengan aman?

FrontendSedang
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Halaman produk membutuhkan indikator progres dan kartu-kartu yang beranimasi saat memasuki viewport. Rancang implementasi berbasis scroll, jelaskan timeline progres scroll versus view, dukung browser lama, serta pertahankan performa dan aksesibilitas.

Perintah dan use case

Tujuannya adalah mengaitkan progres animasi dengan scrolling tanpa menjalankan JavaScript handler pada setiap event scroll. Animasi berbasis scroll CSS mengekspos timeline scroll-progress dan view-progress melalui animation-timeline, scroll(), dan view(). Implementasinya tetap memerlukan fallback, perilaku reduced-motion, keputusan containment, dan kebijakan dukungan browser yang jelas.

Apa yang dievaluasi pewawancara

  • Apakah Anda membedakan progres wadah scroll dari progres visibilitas suatu elemen.
  • Apakah Anda menempatkan deklarasi animation-timeline setelah shorthand animation.
  • Apakah Anda memilih transform dan opacity sebelum properti yang memicu layout.
  • Apakah Anda menyediakan feature query atau baseline non-animasi.
  • Apakah Anda menghormati prefers-reduced-motion dan mempertahankan konten yang dapat dibaca tanpa gerakan.
  • Apakah Anda mengukur halaman panjang, scroller bersarang, elemen sticky, dan performa seluler.

Klarifikasi sebelum menjawab

  • Apakah progres terikat pada halaman, wadah scroll bersarang, atau elemen yang memasuki viewport?
  • Apakah animasi harus mengomunikasikan status, atau hanya bersifat dekoratif?
  • Browser dan webview tersemat mana saja yang masuk dalam cakupan?
  • Apa yang harus dilihat oleh pengguna dengan preferensi reduced motion?
  • Bisakah desain diturunkan (degrade) menjadi bilah progres statis atau tampilan langsung tanpa animasi?
  • Apakah ada ancestor sticky, tertransformasi, atau tervirtualisasi yang mengubah containing block?

Kerangka jawaban 30 detik

“Saya akan menggunakan scroll-progress timeline untuk progres halaman dan view-progress timeline untuk kartu yang memasuki scroller. Saya akan mendefinisikan baseline statis yang dapat dibaca, lalu menyempurnakannya di dalam feature query dengan animation-timeline yang dideklarasikan setelah shorthand animasi. Saya akan menganimasikan transform atau opacity, menguji scroller bersarang dan elemen sticky, serta menonaktifkan gerakan yang tidak penting pada prefers-reduced-motion. Saya akan memverifikasi dukungan, biaya frame, akses keyboard, dan pemahaman konten sebelum merilisnya.”

Jawaban mendalam langkah demi langkah

Langkah 1: Pilih timeline.

Gunakan scroll-progress timeline saat animasi dipetakan ke rentang scroll dari suatu wadah. Gunakan view-progress timeline saat animasi dipetakan ke pergerakan elemen yang melintasi scrollport.

Langkah 2: Bangun baseline.

Render indikator progres dan kartu dalam keadaan statis yang fungsional terlebih dahulu. Browser yang mengabaikan animasi harus tetap menampilkan konten, urutan, kontras, dan kontrol.

Langkah 3: Tambahkan peningkatan CSS.

css
@supports (animation-timeline: scroll()) {
  .progress {
    animation: grow-progress linear both;
    animation-timeline: scroll(root block);
  }

  .card {
    animation: reveal linear both;
    animation-timeline: view(block);
    animation-range: entry 0% cover 35%;
  }
}

Deklarasikan animation-timeline setelah shorthand karena shorthand mereset sub-properti yang terkait dengan timeline. Beri nama timeline secara eksplisit ketika wadah scroll bersarang dapat membuat scroller terdekat menjadi ambigu.

Langkah 4: Jaga agar properti yang dianimasikan tetap hemat biaya.

Utamakan opacity dan transform. Hindari menganimasikan width, height, top, left, atau bayangan besar pada daftar yang panjang kecuali profiling membuktikan biayanya dapat diterima. Jangan menambahkan will-change ke setiap kartu hanya berdasarkan tebakan.

Langkah 5: Tangani reduced motion.

css
@media (prefers-reduced-motion: reduce) {
  .progress,
  .card {
    animation: none;
    transform: none;
    opacity: 1;
  }
}

Konten dan makna progres harus tetap tersedia tanpa animasi. Status instan yang halus atau indikator statis lebih aman daripada sekadar memperpendek durasi transisi yang panjang.

Langkah 6: Uji geometri dan dukungan.

Uji scroller root, scroller bersarang horizontal dan vertikal, elemen sticky, konten dinamis, zoom, navigasi keyboard, dan perubahan viewport seluler. Deteksi fitur harus mengontrol peningkatan, bukan menyembunyikan baseline.

Langkah 7: Ukur dan amati.

Gunakan trace performa DevTools untuk memeriksa pekerjaan style, layout, paint, dan compositor. Uji daftar panjang dan perangkat seluler berdaya rendah, serta pantau konten yang menjadi tidak terbaca saat timeline tidak didukung atau terputus.

Contoh jawaban berkualitas tinggi

“Bilah progres halaman menggunakan scroll(root block) karena nilainya adalah rentang scroll root. Setiap kartu menggunakan view(block) dengan rentang entry-to-cover karena pemunculannya harus mengikuti visibilitasnya sendiri. Saya merender kartu secara normal terlebih dahulu, lalu menambahkan timeline di dalam @supports; deklarasinya mengikuti shorthand animasi. Saya membatasi gerakan pada transform dan opacity, menghapus animasi yang tidak penting bagi pengguna reduced-motion, dan menamai scroller saat hierarki bersarang membuat wadah terdekat menjadi ambigu. Saya menguji akses keyboard, konten sticky dan dinamis, browser yang tidak didukung, dan daftar seluler panjang dengan trace performa.”

Kesalahan umum

  • Menggunakan scroll event untuk setiap frame → pekerjaan handler dapat bersaing dengan scrolling → pilih timeline CSS saat hubungannya bersifat deklaratif.
  • Membingungkan scroll() dan view() animasi dimulai pada momen yang salah → petakan timeline ke progres wadah atau visibilitas elemen.
  • Menaruh animation-timeline sebelum shorthand → shorthand dapat meresetnya → deklarasikan timeline setelahnya.
  • Menganimasikan properti layout secara default → halaman panjang dapat memicu pemrosesan yang berat → mulai dengan transform dan opacity, lalu lakukan profiling.
  • Merilis animasi tanpa penanganan reduced-motion → pengguna kehilangan kendali atas preferensi mereka → sediakan status statis.
  • Menyembunyikan konten hingga dukungan animasi tersedia → browser yang tidak mendukung akan kehilangan informasi → bangun baseline terlebih dahulu.
  • Mengasumsikan scroller terdekat selalu benar → wadah bersarang mengubah timeline → beri nama atau uji scroller yang dimaksud.

Pertanyaan lanjutan dan tanggapan

Lanjutan 1: Apa perbedaan antara scroll() dan view()?

scroll() melacak progres wadah scroll. view() melacak progres visibilitas elemen melalui scrollport wadah tersebut.

Lanjutan 2: Mengapa timeline harus diletakkan setelah shorthand?

Shorthand animation mereset sub-properti yang terkait dengan timeline, sehingga deklarasi timeline sebelumnya dapat terhapus.

Lanjutan 3: Apa fallback-nya?

Pertahankan konten agar tetap terlihat dalam kondisi akhir yang dapat dibaca dan gunakan indikator progres statis atau sedikit peningkatan JavaScript hanya jika kebutuhan produk benar-benar memerlukannya.

Lanjutan 4: Bagaimana Anda mendukung reduced motion?

Nonaktifkan animasi yang tidak penting, hapus transform, dan pertahankan konten serta makna status yang sama dengan gaya statis.

Lanjutan 5: Bisakah Anda menganimasikan height?

Hanya setelah profiling dan dengan kebutuhan yang jelas. Transform dan opacity biasanya menghindari pekerjaan layout; menganimasikan height dapat membatalkan layout di seluruh elemen saudaranya (siblings).

Lanjutan 6: Apa yang terjadi pada scroller bersarang?

Wadah scroll terdekat yang berlaku mungkin berbeda dari halaman. Uji geometrinya dan beri nama timeline yang dimaksud atau gunakan argumen scroller yang benar.

Lanjutan 7: Bagaimana Anda memverifikasinya di produksi?

Catat penggunaan dukungan browser, trace performa pada perangkat yang representatif, perilaku reduced-motion, dan pemeriksaan aksesibilitas. Pertahankan baseline statis agar timeline yang tidak didukung atau terputus tetap dapat digunakan.

Sumber publik

Pertanyaan terkait