Petunjuk dan cakupan
Sebuah produk menginginkan efek View Transition API untuk perubahan rute SPA dan pembukaan tampilan detail gambar. Jelaskan implementasinya dan bagaimana Anda menangani peramban lama, prefers-reduced-motion, data asinkron, fokus, kegagalan animasi, dan fallback performa.
Ini menguji batasan API dan peningkatan bertahap (progressive enhancement), bukan sekadar animasi demo. MDN mendefinisikan document.startViewTransition() sebagai titik masuk pembaruan dokumen yang sama dan menyatakan bahwa transisi berlanjut setelah callback selesai; transisi lintas-dokumen juga memerlukan origin yang sama dan CSS @view-transition. Animasi harus melayani perubahan status dan tidak boleh menghalangi kegunaan (usability).
Apa yang sedang diuji oleh pewawancara
Pertama, dapatkah Anda membedakan transisi SPA dokumen yang sama, cakupan elemen, dan lintas-dokumen? Kedua, dapatkah Anda menangani API yang tidak didukung, callback yang ditolak, reduced motion, dan keluar dari halaman? Ketiga, dapatkah Anda mempertahankan fokus, DOM semantik, scrolling, dan interaksi nyata alih-alih menyembunyikannya di balik animasi snapshot?
Pertanyaan untuk diklarifikasi sebelum menjawab
- Batasan apa yang sedang bertransisi? Pembaruan DOM dokumen yang sama, satu elemen, atau navigasi antardokumen?
- Apakah pembaruan menyertakan data asinkron? Apa yang harus siap terlebih dahulu, dan berapa batas waktu tunggu maksimum?
- Bagaimana pengalaman yang dapat diterima untuk peramban lama? Pembaruan status yang sama harus berfungsi tanpa animasi.
- Pengguna mana yang mengurangi atau menonaktifkan gerakan? Bagaimana
prefers-reduced-motiondan pengaturan aplikasi digabungkan? - Bagaimana status halaman dipulihkan? Fokus, scroll, input formulir, dan navigasi kembali?
- Berapa anggaran performanya? Cakupan snapshot, durasi, perangkat low-end, dan transisi bersamaan (concurrent)?
Kerangka jawaban 30 detik
"Saya akan memisahkan pembaruan status dari animasi: jika didukung, bungkus pembaruan DOM sinkron dalam startViewTransition; jika tidak, jalankan pembaruan yang sama secara langsung. Siapkan data asinkron di rute atau komponen, jaga agar callback tetap fokus untuk menerapkan status yang siap, dan amati ready, finished, dan skipTransition. Gunakan named views untuk membatasi cakupan, persingkat atau nonaktifkan gerakan di bawah prefers-reduced-motion, pulihkan fokus dan scroll, serta pastikan kegagalan animasi tidak menghalangi interaksi. Validasi tugas panjang (long tasks), jumlah snapshot, waktu penyelesaian, dan tingkat fallback pada perangkat low-end."
Pembahasan mendalam langkah demi langkah
Langkah 1: Tentukan pembaruan status dan tujuan animasi
Beri nama dua status yang dihubungkan oleh animasi, seperti kartu daftar ke halaman detail atau hasil yang difilter ke daftar baru, alih-alih memudarkan seluruh halaman tanpa pandang bulu. Pembaruan harus tetap benar tanpa animasi; animasi adalah lapisan peningkatan. Tentukan nama transisi yang diizinkan dan perilaku fallback untuk setiap jenis navigasi.
Langkah 2: Deteksi dukungan dan pertahankan fallback sinkron
Periksa document.startViewTransition sebelum memanggilnya. Peramban yang tidak mendukung akan mengeksekusi fungsi pembaruan yang sama secara langsung; jangan menduplikasi logika bisnis. Dukungan peramban baru tidak mencakup semua perangkat lama, jadi pertahankan jalur fallback sebagaimana disyaratkan oleh panduan kompatibilitas MDN.
Langkah 3: Batasi callback dan data asinkron
updateCallback berjalan setelah snapshot tampilan lama; Promise yang dikembalikan harus terpenuhi sebelum frame berikutnya. Ambil data sebelum memulai jika memungkinkan. Jika callback harus menunggu, tetapkan batas waktu (timeout) dan izinkan transisi dilewati. Callback yang ditolak mengikuti penanganan kesalahan bisnis normal dan tidak boleh mengekspos halaman yang diperbarui setengah jalan.
const update = () => renderState(nextState);
if (!document.startViewTransition || reduceMotion) {
update();
} else {
const transition = document.startViewTransition(update);
transition.finished.catch(() => {
// Animation failure does not roll back the completed state update.
});
}Langkah 4: Batasi snapshot dengan named views
Berikan view-transition-name yang unik hanya untuk elemen yang benar-benar berbagi posisi. Komponen daftar yang berulang tidak dapat berbagi satu nama tanpa ambiguitas. Untuk daftar dinamis, hapus nama lama sebelum memperbarui dan tetapkan nama unik yang stabil setelahnya.
Langkah 5: Terapkan reduced motion dan perilaku aksesibel
Dengarkan prefers-reduced-motion: reduce, atur durasi ke nol atau mendekati nol, dan pertahankan perubahan status. Jangan menyembunyikan fokus keyboard atau mengomunikasikan hasil hanya melalui warna. Setelah pembaruan, pindahkan fokus ke judul tampilan baru atau yang setara. web.dev memperingatkan bahwa animasi transisi tampilan layar penuh dapat membuat orang dengan gangguan vestibular merasa tidak nyaman.
Langkah 6: Tangani perbedaan SPA, elemen, dan lintas-dokumen
SPA membungkus pembaruan DOM-nya dengan document.startViewTransition; transisi berlingkup elemen memengaruhi elemen pemanggil dan turunannya; navigasi lintas-dokumen memerlukan origin yang sama dan keikutsertaan (opt-in) @view-transition di kedua dokumen. Jangan berasumsi bahwa callback JS dokumen yang sama ada di seluruh siklus hidup dokumen.
Langkah 7: Rancang jalur lewati (skip), konkurensi, dan kegagalan
Untuk klik cepat, batalkan atau gabungkan navigasi usang agar transisi tidak bersaing untuk node yang sama. Gunakan skipTransition() atau batas waktu untuk mengakhiri animasi yang macet. Setelah status bisnis diperbarui, kegagalan visual tidak boleh menyebabkan pengiriman ganda, permintaan duplikat, atau rollback yang salah.
Langkah 8: Validasi performa dan pengalaman pengguna nyata
Pantau waktu dari awal hingga selesai, rasio lewati, tugas panjang, CLS, penundaan input, dan kesalahan pada perangkat low-end. Uji daftar besar, jaringan lambat, pekerjaan asinkron yang ditolak, navigasi kembali yang cepat, pembaca layar (screen reader), dan reduced motion. Pastikan snapshot dan animasi tidak pernah membuat interaksi nyata menunggu lebih lama.
Pertukaran (Trade-offs) dan batasan
Trade-off 1: Transisi satu halaman penuh atau lokal
Transisi satu halaman penuh lebih sederhana tetapi membutuhkan lebih banyak biaya snapshot dan dapat mengganggu fokus serta scroll. Transisi lokal memerlukan nama yang stabil dan batasan komponen yang tepat, menjadikannya lebih baik untuk interaksi yang sering dan halaman besar.
Trade-off 2: Menunggu data atau langsung bertransisi
Menunggu akan menghindari ketidakcocokan konten lama/baru tetapi meningkatkan waktu respons. Lebih utamakan prefetching; jika tidak, tampilkan status pemuatan eksplisit. Transisi bukanlah pengganti umpan balik pemuatan (loading feedback).
Trade-off 3: Animasi kustom atau default peramban
Nilai default lebih aman dan lebih mudah dirawat. Timpa animasi pseudo-elemen hanya jika memiliki semantik navigasi yang jelas dan anggaran verifikasi, serta sediakan status statis yang sama fungsionalnya untuk reduced motion.
Latihan kegagalan dan rencana evolusi
Latihan 1: Peramban tidak didukung atau callback ditolak
Perbarui langsung di peramban yang tidak didukung, tolak Promise, dan verifikasi status halaman tetap benar. Catat hanya informasi diagnostik dan jangan pernah memblokir interaksi yang sedang berlangsung.
Latihan 2: Navigasi cepat dan race condition asinkron
Klik dua tautan dengan cepat sambil membuat permintaan pertama lebih lambat. Verifikasi bahwa transisi yang usang tidak dapat menimpa status saat ini, fokus mendarat di halaman saat ini, dan tidak ada permintaan efek samping duplikat yang dikirim.
Latihan 3: Reduced motion dan perangkat low-end
Aktifkan reduced motion sistem dan jalankan transisi daftar besar pada perangkat dengan CPU terbatas. Konfirmasikan bahwa animasi dinonaktifkan atau dipersingkat sementara penundaan input dan stabilitas tata letak tetap berada dalam anggaran.
Kesalahan umum dan tindak lanjut
Kesalahan 1: Tidak ada jalur fallback
API yang tidak didukung harus tetap menghasilkan pembaruan DOM atau rute yang sama. Peningkatan bertahap tidak dapat mengikat status bisnis pada keberhasilan animasi.
Kesalahan 2: Menunggu jaringan selamanya di dalam callback
Menunggu lama setelah snapshot akan membekukan halaman lama. Siapkan data lebih awal atau tetapkan batas waktu dan lewati animasi.
Kesalahan 3: Memberi banyak elemen satu nama bersama
Nama duplikat menciptakan ambiguitas pencocokan dan snapshot tambahan. Beri nama hanya pada elemen yang benar-benar berpindah dan jaga agar namanya unik dan stabil.
Kesalahan 4: Mengabaikan fokus dan scroll
Transisi visual yang selesai tidak mengembalikan pengguna keyboard ke tempat yang tepat. Pulihkan fokus, scroll, dan heading semantik secara eksplisit.
Kesalahan 5: Memperlakukan reduced motion sebagai penghapusan fitur
Pengguna meminta lebih sedikit gerakan, bukan pengurangan status atau informasi. Pertahankan interaksi yang sama dan ubah hanya presentasi animasinya.
Kesalahan 6: Melakukan rollback status bisnis saat animasi gagal
Penolakan finished biasanya mendeskripsikan kegagalan tahap visual. Jangan mengirim ulang atau membatalkan pembaruan status yang sudah berhasil.