Ekstensi Chrome: Memperluas API untuk mendukung Navigasi Instan

Dave Tapuska
Dave Tapuska

TL;DR: Extensions API telah diupdate untuk mendukung back/forward cache, melakukan pramuat navigasi. Lihat detailnya di bawah ini.

Chrome telah bekerja keras untuk membuat navigasi menjadi cepat. Navigasi Instan teknologi seperti Back/Forward Cache (dikirim di desktop dalam Chrome 96) dan Aturan Spekulasi (dikirimkan di Chrome 103) meningkatkan kualitas proses mundur dan maju pengalaman yang lancar bagi developer. Dalam postingan ini, kita akan mempelajari update yang telah dilakukan pada browser API ekstensi untuk mengakomodasi alur kerja baru ini.

Memahami jenis-jenis halaman

Sebelum pengenalan Back/Forward Cache dan pra-rendering, individu tab hanya memiliki satu halaman aktif. Inilah yang selalu terlihat. Jika pengguna kembali ke halaman sebelumnya, halaman aktif akan dihancurkan (Halaman B) dan laman sebelumnya dalam riwayat akan direkonstruksi sepenuhnya (Halaman A). Ekstensi tidak perlu mengkhawatirkan bagian mana dari halaman siklus proses yang karena hanya ada satu untuk tab, yaitu status aktif/terlihat.

Penghapusan halaman aktif
Penghapusan halaman aktif.

Dengan Back/Forward Cache dan pra-rendering, tidak ada lagi one-to-one hubungan antara tab dan laman. Sekarang, setiap tab benar-benar menyimpan beberapa halaman dan halaman beralih antarstatus, bukannya dihancurkan dan direkonstruksi.

Misalnya, sebuah halaman dapat memulai prosesnya sebagai halaman pra-rendering (tidak terlihat), bertransisi ke halaman aktif (terlihat) saat pengguna mengklik link, lalu disimpan di Back/Forward Cache (tidak terlihat) saat pengguna membuka halaman lain, semuanya tanpa pernah memusnahkan halamannya. Nanti di artikel ini kita akan melihat properti baru yang diekspos untuk membantu ekstensi memahami halaman negara bagian.

Jenis halaman
Jenis halaman.

Perhatikan bahwa tab dapat memiliki serangkaian laman pra-rendering (bukan hanya satu), satu active (terlihat), dan serangkaian halaman Back/Forward yang di-cache.

Apa saja yang berubah bagi developer ekstensi?

IdBingkai == 0

Di Chromium, kami menyebut frame paling atas/utama sebagai frame terluar.

Penulis ekstensi yang menggunakan frameId dari {i>frame<i} terluar adalah 0 (praktik terbaik sebelumnya) mungkin bermasalah. Karena tab kini dapat memiliki beberapa frame terluar (pra-rendering dan di-cache halaman), dengan asumsi bahwa ada satu elemen terluar {i>frame<i} untuk tab salah. frameId == 0 akan terus mewakili frame terluar halaman aktif, tetapi frame terluar halaman other di tab yang sama akan menjadi bukan nol. Kolom baru frameType memiliki telah ditambahkan untuk mengatasi masalah ini. Lihat bagian “Bagaimana cara menentukan apakah bingkai merupakan bingkai terluar?” dari postingan ini.

Siklus proses frame versus dokumen

Konsep lain yang bermasalah dengan ekstensi adalah siklus hidup dari {i>frame<i}. Frame menghosting dokumen (yang terkait dengan URL yang di-commit). Dokumen dapat berubah (misalnya dengan menavigasi), tetapi frameId tidak, dan karenanya sulit mengaitkan sesuatu yang terjadi dalam dokumen tertentu dengan cukup frameIds. Kami memperkenalkan konsep documentId yang merupakan pengidentifikasi unik untuk setiap dokumen. Jika {i>frame<i} dinavigasi dan membuka dokumen baru yang akan diubah pengenalnya. Bidang ini berguna untuk menentukan kapan halaman mengubah status siklus prosesnya (antara pra-rendering/active/cache) karena tetap sama.

Peristiwa navigasi web

Peristiwa di namespace chrome.webNavigation dapat diaktifkan beberapa kali pada halaman yang sama tergantung pada siklus hidupnya. Lihat “Bagaimana cara mengetahui siklus proses apa yang ada di halaman?” dan bagian “Bagaimana cara menentukan waktu transisi halaman?”.

Bagaimana cara mengetahui siklus proses apa yang ada di halaman?

DocumentLifecycle telah ditambahkan ke sejumlah API ekstensi tempat frameId sebelumnya tersedia. Jika jenis DocumentLifecycle ada pada peristiwa (seperti onCommitted), nilainya adalah status tempat peristiwa dibuat. Anda selalu dapat mengkueri informasi dari WebNavigation getFrame() dan getAllFrames() , namun menggunakan nilai dari peristiwa akan selalu disukai. Jika Anda menggunakan salah satu metode tersebut mengetahui status {i>frame<i} dapat berubah antara saat peristiwa dibuat dan saat promise yang ditampilkan oleh kedua metode tersebut diselesaikan.

DocumentLifecycle memiliki nilai berikut:

  • "prerender inci : Saat ini tidak ditampilkan kepada pengguna, tetapi bersiap untuk ditampilkan kepada pengguna.
  • "active": Ditampilkan kepada pengguna.
  • "cached": Disimpan dalam Back/Forward Cache.
  • "pending_deletion": Dokumen sedang dihancurkan.

Bagaimana cara menentukan apakah {i>frame<i} adalah {i>frame<i} terluar?

Sebelumnya, ekstensi mungkin telah memeriksa apakah frameId == 0 menentukan jika kejadian yang terjadi adalah untuk {i>frame<i} terluar atau tidak. Dengan beberapa halaman Di tab, kita sekarang memiliki beberapa bingkai terluar, sehingga definisi frameId yang bermasalah. Anda tidak akan pernah menerima peristiwa tentang Back/Forward yang di-cache {i>frame<i}. Namun, untuk frame yang telah dipra-render, frameId akan bukan nol untuk {i>frame<i} terluar. Jadi menggunakan frameId == 0 sebagai sinyal untuk menentukan apakah bingkai terluar salah.

Untuk membantu melakukan hal ini, kami memperkenalkan tipe baru yang disebut FrameType Jadi, menentukan apakah {i>frame<i} memang adalah {i>frame<i} terluar itu sekarang mudah. FrameType memiliki nilai berikut:

  • "outermost_frame": Biasanya disebut sebagai bingkai paling atas. Perlu diketahui bahwa ada kelipatan. Misalnya, jika Anda memiliki pra-rendering dan di-cache laman, masing-masing memiliki {i>frame<i} terluar yang bisa disebut {i>frame<i} paling atas.
  • "fenced_frame": Dicadangkan untuk penggunaan pada masa mendatang.
  • "sub_frame": Biasanya iframe.

Kita dapat menggabungkan DocumentLifecycle dengan FrameType dan menentukan apakah suatu frame {i>frame<i} terluar yang aktif. Contoh: tab.documentLifecycle === “active” && frameType === “outermost_frame”

Bagaimana cara mengatasi masalah waktu penggunaan dengan frame?

Seperti yang kami katakan di atas, {i>frame<i} meng-{i>host<i} dokumen dan {i>frame<i} dapat menavigasi ke direktori dokumen, tetapi frameId tidak akan berubah. Hal ini menimbulkan masalah ketika Anda menerima peristiwa hanya dengan frameId. Jika Anda mencari URL dalam {i>frame<i} itu mungkin berbeda dari ketika peristiwa terjadi, hal ini disebut masalah waktu penggunaan.

Untuk mengatasinya, kami memperkenalkan documentId (dan parentDocumentId). webNavigation.getFrame() kini menjadikan frameId opsional jika documentId disediakan. Tujuan documentId akan berubah setiap kali frame dibuka.

Bagaimana cara menentukan kapan halaman bertransisi?

Ada sinyal eksplisit untuk menentukan kapan transisi halaman antarstatus.

Mari kita lihat peristiwa WebNavigation.

Untuk navigasi pertama pada halaman, Anda akan melihat empat peristiwa secara berurutan yang tercantum di bawah ini. Perhatikan bahwa keempat peristiwa ini dapat terjadi dengan Status DocumentLifecycle adalah "prerender" atau "active".

onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted

Hal ini diilustrasikan dalam diagram di bawah yang menunjukkan perubahan documentId ke "xyz" saat halaman pra-rendering menjadi halaman aktif.

DocumentId berubah saat halaman pra-rendering menjadi halaman aktif
documentId akan berubah saat halaman yang dipra-render menjadi halaman aktif.

Saat halaman bertransisi dari Back/Forward Cache atau pra-rendering ke status aktif, akan ada tiga peristiwa lagi (tetapi dengan DocumentLifecyle menjadi "active").

onBeforeNavigate
onCommitted
onCompleted

documentId akan tetap sama seperti pada peristiwa asli. Ini adalah yang diilustrasikan di atas saat documentId == xyz diaktifkan. Perhatikan bahwa peristiwa navigasi yang sama diaktifkan, kecuali untuk onDOMContentLoaded karena halaman sudah dimuat.

Jika ada komentar atau pertanyaan, jangan ragu untuk bertanya di chromium-extensions ras.