Gesaan dan konteks
Bagaimanakah anda akan mereka bentuk semula lapisan navigasi SPA supaya boleh dipulihkan dan boleh diperhatikan tanpa merosakkan sejarah pelayar? Terangkan perlumbaan pemuatan, pemulihan ralat, pemulihan tatalan, dan sandaran apabila Navigation API tidak tersedia.
Soalan ini sesuai untuk peranan frontend, full-stack, dan platform web. Ia menguji model navigasi pelayar, mesin keadaan tak segerak (asynchronous state machines), dan peningkatan progresif dan bukannya konfigurasi rangka kerja yang dihafal. Navigation API menyediakan paparan bersatu bagi navigasi dokumen sama melalui peristiwa seperti navigate, navigatesuccess, dan navigateerror, serta intercept(). Ia tidak menggantikan pemuatan awal yang direncanakan pelayan atau mengubah sempadan keselamatan navigasi rentas dokumen.
Perkara yang dinilai oleh penemu duga
- Menganggap URL dan entri sejarah sebagai keadaan navigasi, bukan hanya memori komponen.
- Membezakan laluan dokumen sama daripada dokumen penuh, muat turun, borang, dan pautan rentas asal (cross-origin).
- Mengendalikan permintaan lapuk, pembatalan, ralat, dan navigasi ke belakang/ke hadapan.
- Menentukan peraturan pemulihan tatalan, fokus, dan keadaan halaman.
- Memastikan pemuatan pertama dan pelayar yang tidak disokong kekal berfungsi.
- Mengukur kejayaan, kegagalan, tamat masa, pembatalan, dan pemulihan.
Jawapan 30 saat
“Saya akan memastikan titik masuk yang direncanakan pelayan dan pautan biasa berfungsi, dengan URL dan sejarah sebagai punca kebenaran. Apabila Navigation API tersedia, saya hanya akan memintas laluan aplikasi asal sama, memulakan pemuatan yang boleh dibatalkan dalam peristiwa navigate, dan membiarkan navigasi yang lebih baharu membatalkan navigasi yang lebih lama. Hanya tugasan semasa yang boleh melakukan komit pada paparan. Jika berjaya, saya memulihkan tatalan dan fokus; jika gagal, saya mengekalkan paparan lama dan menawarkan cuba semula atau muat semula. Pelayar yang tidak disokong menggunakan laluan History API sedia ada, berkongsi pemuat dan metrik yang sama.”
Penyelesaian langkah demi langkah
Langkah 1: Hadkan navigasi yang anda pintas
Semak sama ada destinasi adalah asal sama, laluan aplikasi, dan selamat untuk direncanakan dalam dokumen semasa. Pautan luaran, muat turun, destinasi rentas asal, protokol khas, dan semantik borang harus mengekalkan tingkah laku lalai pelayar. Permintaan dokumen pertama masih milik pelayan dan pelayar; peristiwa navigate tidak boleh menjadikan pemuatan skrip yang gagal boleh dipulihkan dengan sendirinya.
Panggil intercept() hanya untuk laluan aplikasi yang diluluskan. Pengendali memuatkan data, mengemas kini paparan, dan menggunakan dasar tatalan. Bagi setiap destinasi lain, benarkan pelayar menavigasi seperti biasa. Ini mengekalkan semantik pautan dan mengelakkan navigasi platform daripada bertukar menjadi mesin keadaan khusus klien secara tidak sengaja.
Langkah 2: Jadikan navigasi boleh dibatalkan
Berikan nombor jujukan yang meningkat kepada setiap navigasi dan hantar AbortSignal kepunyaannya kepada pemuat data. Jika pengguna beralih daripada /search?q=a ke /search?q=ab, respons yang lewat daripada permintaan pertama tidak boleh menulis ganti permintaan kedua. Sebelum melakukan komit, pastikan isyarat belum dibatalkan, jujukan adalah semasa, dan destinasi masih sepadan dengan keadaan yang dimaksudkan.
let latestNavigation = 0;
navigation.addEventListener("navigate", (event) => {
if (!event.canIntercept || !isAppRoute(event.destination.url)) return;
const id = ++latestNavigation;
event.intercept({
async handler() {
const data = await loadRoute(event.destination.url, event.signal);
if (event.signal.aborted || id !== latestNavigation) return;
renderRoute(data);
}
});
});Contoh ini menunjukkan peraturan perlumbaan, bukan penghala yang lengkap. Kod pengeluaran masih memerlukan ralat pemuat, tamat masa, capaian cache, dan pembongkaran komponen. “Respons terakhir menang” adalah salah kerana urutan penyiapan rangkaian bukanlah niat terkini pengguna.
Langkah 3: Komit sejarah, tatalan, dan keadaan halaman
Selepas navigasi berjaya, komit URL destinasi sebagai hasilnya. Jika nilai kecil yang boleh dipulihkan tergolong dalam entri sejarah semasa, updateCurrentEntry() boleh menyimpannya; objek besar dan data sensitif tidak sepatutnya berada di sana. Dasar tatalan harus membezakan laluan baharu, ke belakang/ke hadapan, dan sauh (anchor): laluan baharu biasanya bermula di bahagian atas, manakala pelayaran sejarah memulihkan kedudukan yang disimpan.
Elakkan menukar tajuk, item yang dipilih, atau jejak serbuk roti (breadcrumb) pada permulaan pemuatan melainkan UI secara eksplisit mewakili keadaan yang belum selesai. Komit keadaan visual utama selepas berjaya, dan kekalkan kandungan lama dengan tindakan cuba semula selepas kegagalan. navigatesuccess dan navigateerror ialah titik pemerhatian yang berguna untuk metrik kependaman, pembatalan, dan kegagalan.
Langkah 4: Pulih daripada ralat
Halaman lama harus kekal boleh digunakan apabila pemuatan gagal. Sediakan tindakan cuba semula, kembali, dan muat semula penuh, serta bezakan pengesahan, kebenaran, sumber yang hilang, dan kegagalan rangkaian sementara. Jika destinasi memerlukan respons dokumen penuh, hentikan pemintasan dan biarkan pelayar mengendalikannya.
Jika keadaan klien atau pelaksanaan skrip rosak, pautan biasa dan laluan pelayan mesti tetap membina semula halaman daripada URL. Jangan jadikan pemulihan bergantung pada cache dalam memori. Rekodkan destinasi, jujukan navigasi, kelas ralat, dan sama ada sandaran berlaku supaya situasi “alamat bertukar tetapi halaman lama kekal” boleh didiagnosis.
Langkah 5: Gunakan peningkatan progresif
Sokongan Navigation API lebih baharu daripada garis dasar History API, jadi ia tidak boleh menjadi satu-satunya laluan. Kesan window.navigation dan kaedah yang anda gunakan secara sebenar, kemudian pilih laluan yang dipertingkatkan. Pelayar yang tidak disokong harus menggunakan semula pemuat laluan yang sama melalui History API atau penghala rangka kerja sedia ada; jangan pisahkan peraturan perniagaan semata-mata untuk keserasian.
Uji pemuatan pertama, muat semula, ke belakang/ke hadapan, pautan yang terganggu, dan kegagalan skrip dalam kedua-dua laluan keupayaan. Sertakan rangkaian perlahan, navigasi pantas, pautan rentas asal, dan muat turun. Pengesanan keupayaan harus dilakukan berdekatan dengan penggunaan ciri dan bukannya senarai versi pelayar yang rapuh.
Langkah 6: Sahkan prestasi dan kebolehcapaian
Gunakan tugasan sebenar: carian, penapisan, kembali, muat semula, pautan dalam (deep links), dan cuba semula. Ukur masa untuk interaktif, kadar pembatalan, kadar kegagalan, kadar sandaran, dan permintaan pendua, yang dikumpulkan mengikut keupayaan pelayar. Masa persembahan komponen sahaja tidak dapat menerangkan kegagalan data, kebenaran, atau sejarah.
Kekalkan semantik pautan asli, tingkah laku papan kekunci, dan pergerakan fokus yang boleh diakses. Selepas navigasi yang dipintas, kemas kini tajuk dokumen dan alihkan fokus ke kandungan utama; jangan halang pembukaan pautan dalam tab baharu. Caching mungkin mengurangkan kependaman, tetapi ia tidak boleh menjadi satu-satunya punca dari mana halaman boleh dipulihkan.
Keuntungan maklumat dan sempadan
Perbezaan yang berguna ialah Navigation API menggabungkan peristiwa navigasi platform, sejarah, dan pemuatan yang boleh dibatalkan ke dalam satu rantaian keadaan. Ia tidak menjadikan sumber data boleh dipercayai atau menukar halaman rentas asal kepada laluan dokumen sama. Jawapan temu duga yang mantap menyatakan sempadan pemintasan, titik komit, tingkah laku paparan lama semasa kegagalan, dan tingkah laku lalai apabila pelayar tidak mempunyai keupayaan tersebut.
Jawapan model
“Saya akan mengklasifikasikan navigasi kepada laluan aplikasi asal sama, dokumen penuh, muat turun, borang, dan destinasi rentas asal, serta hanya memintas kelas yang pertama. Titik masuk pelayan dan pautan biasa kekal sah, dengan URL dan sejarah sebagai punca kebenaran. Dengan Navigation API, peristiwa navigate memanggil intercept() dan mencipta nombor jujukan berserta isyarat pembatalan. Navigasi yang lebih baharu membatalkan pemuatan lama, dan hasilnya hanya dikomit jika ia masih terkini.
Selepas berjaya, saya mengemas kini paparan, tajuk, fokus, dan dasar tatalan. Laluan baharu bermula di bahagian atas; ke belakang dan ke hadapan memulihkan kedudukan sejarah. Keadaan kecil yang boleh dipulihkan boleh menggunakan entri sejarah semasa, manakala data besar atau sensitif kekal di tempat lain. Sekiranya gagal, saya mengekalkan paparan lama, menawarkan pilihan cuba semula, kembali, atau muat semula penuh, dan merekodkan kependaman, pembatalan, serta kelas ralat melalui peristiwa navigasi dan log pelayan.
Sekiranya Navigation API tidak tersedia, pemuat yang sama berjalan melalui History API atau penghala rangka kerja; pautan luaran dan muat turun sentiasa menggunakan tingkah laku lalai pelayar. Saya akan mengesahkan pautan dalam, muat semula, klik pantas, rangkaian perlahan, pautan rentas asal, kegagalan skrip, dan tugasan teknologi bantuan untuk memastikan alamat, kandungan, fokus, dan sejarah tidak pernah bercanggah. Hasilnya ialah lapisan navigasi progresif dan bukannya penggantian khusus klien yang hanya berfungsi dalam pelayar baharu.”
Kesilapan lazim
- Memintas setiap pautan → muat turun, borang, dan semantik rentas asal rosak → pintas hanya laluan aplikasi asal sama yang diluluskan.
- Membiarkan respons terakhir menang → data lapuk boleh menulis ganti niat semasa → gunakan pembatalan dan semakan jujukan.
- Menguji persembahan sahaja → kegagalan data, kebenaran, dan sejarah kekal tersembunyi → uji keseluruhan tugasan navigasi dan pemulihan.
- Menganggap Navigation API sebagai infrastruktur muatan pertama → muat semula atau kegagalan skrip menjadi tidak boleh dipulihkan → kekalkan respons pelayan dan pautan biasa.
- Meletakkan semua keadaan dalam entri sejarah → entri menjadi terlalu besar atau mendedahkan data sensitif → simpan hanya keadaan kecil yang boleh dibina semula.
- Menduplikasi logik perniagaan untuk sandaran → laluan yang dipertingkatkan dan laluan sandaran terpesong → kongsi pemuat, peraturan keadaan, dan metrik yang sama.
Soalan susulan
Bagaimana jika permintaan lapuk telah mengisi cache?
Penulisan cache mungkin dibenarkan, tetapi komit UI masih memerlukan jujukan semasa dan isyarat yang tidak dibatalkan. Kuncikan entri mengikut URL, parameter, dan versi. Hasil yang lewat boleh memanaskan (warm) permintaan masa hadapan, tetapi ia tidak boleh mengubah halaman semasa.
Patutkah kegagalan kebenaran kembali ke belakang atau mengubah hala ke log masuk?
Gunakan status pelayan yang jelas untuk membezakan pengguna yang tidak disahkan, tidak dibenarkan, dan sumber yang hilang. Pengguna yang tidak disahkan boleh dibawa ke log masuk dengan URL kembali; pengguna yang tidak dibenarkan memerlukan penjelasan dan tindakan selamat seterusnya. Jangan samarkan kebenaran sebagai ralat rangkaian generik.
Bagaimanakah anda menguji pelayar tanpa Navigation API?
Jalankan tugasan pautan dalam, muat semula, ke belakang/ke hadapan, rangkaian perlahan, dan kegagalan yang sama melalui pengesanan keupayaan, dengan menyemak URL, kandungan, tajuk, fokus, dan tatalan. Kesetaraan tingkah laku adalah penting; jujukan peristiwa dalaman tidak perlu serupa secara tepat.
Mengapa tidak bergantung sepenuhnya pada penghala rangka kerja?
Penghala rangka kerja boleh digunakan semula, tetapi jawapan mesti mentakrifkan sempadan pelayar: navigasi mana yang kekal asli, mana yang boleh dipertingkatkan, dan cara pembatalan, sejarah, dan ralat dipetakan ke dalam peristiwa rangka kerja. Mulakan daripada semantik platform, kemudian terangkan penyesuai (adapter).