Cascading cache invalidation. Bagian 2

Pada bagian pertama dari terjemahan materi yang ditujukan untuk cascading invalidation cache, kami membahas sifat masalah dan mempertimbangkan salah satu solusi untuk itu, yang terdiri dari penggunaan kartu impor. Kelebihannya adalah kemudahan implementasi. Dan minus - dukungan browser yang buruk. Hari ini kita akan berbicara tentang cara lain untuk menyelesaikan masalah ini.



Pendekatan # 2: Pekerja Layanan


Solusi kedua untuk masalah ini adalah mereproduksi fungsi kartu impor menggunakan pekerja layanan.

Misalnya, menggunakan pekerja layanan, Anda dapat mendengarkan untuk fetch acara yang ditujukan untuk memuat materi yang terletak di alamat yang terkait dengan kunci kartu impor. Dengan menjalankan permintaan ini, Anda dapat mengunggah file yang namanya menyertakan hash dari isinya:

 const importMap = {  '/main.mjs': '/main-1a2b.mjs',  '/dep1.mjs': '/dep1-b2c3.mjs',  '/dep2.mjs': '/dep2-3c4d.mjs',  '/dep3.mjs': '/dep3-d4e5.mjs',  '/vendor.mjs': '/vendor-5e6f.mjs', }; addEventListener('fetch', (event) => {  const oldPath = new URL(event.request.url, location).pathname;  if (importMap.hasOwnProperty(oldPath)) {    const newPath = importMap[oldPath];    event.respondWith(fetch(new Request(newPath, event.request)));  } }); 

Namun, dengan mempertimbangkan fakta bahwa kode pekerja layanan diberikan di atas, Anda perlu memahami bahwa kode ini hanya akan berfungsi setelah pekerja layanan diinstal dan diaktifkan. Dan ini berarti bahwa ketika Anda pertama kali memuat situs, file akan diminta yang tidak memiliki hash dalam namanya. File dengan hash dalam nama akan diminta pada unduhan situs berikutnya. Dengan kata lain, di sini kita berurusan dengan pemuatan ganda dari setiap file.

Jika Anda mempertimbangkan hal ini, sepertinya pekerja layanan itu bukan solusi yang cocok untuk masalah cascading cache invalidation.

Namun, di sini saya akan meminta Anda untuk mengizinkan saya secara singkat mengkritik pendekatan lama terhadap caching. Mari kita pikirkan apa yang terjadi jika kita berhenti menggunakan hash konten dalam nama file, alih-alih memasukkan informasi hash dalam kode pekerja layanan.

Ini adalah cara alat seperti Workbox yang berfungsi sumber daya pra-cache. Mereka menghasilkan hash dari isi setiap file dari majelis dan menyimpan korespondensi dari nama file di pekerja layanan (ternyata sesuatu seperti kartu impor eksternal). Selain itu, mereka menyimpan sumber daya selama instalasi pertama pekerja layanan dan menambahkan fetch pendengar acara yang mengembalikan file yang di-cache sebagai tanggapan terhadap permintaan yang alamatnya sesuai dengan yang ada di peta impor.

Meskipun gagasan bahwa klien menerima file yang tidak berisi informasi tentang versi kontennya mungkin tampak menakutkan (dan bertentangan dengan semua yang telah diajarkan kepada Anda), permintaan untuk mengunduh sumber daya yang sesuai dijalankan hanya ketika pekerja layanan diinstal. Permintaan lebih lanjut untuk mengunduh sumber daya seperti itu melalui Cache Storage API (yang tidak menggunakan header caching), dan permintaan baru ke server dieksekusi hanya ketika versi baru dari pekerja layanan sedang digunakan (dan Anda tetap memerlukan versi baru dari file-file ini).

Akibatnya, hingga Anda mulai menggunakan versi modul baru tanpa memperbarui pekerja layanan (dan ini jelas tidak disarankan), Anda tidak akan pernah mengalami konflik atau ketidakcocokan versi.

Untuk mengatur caching awal file menggunakan pustaka workbox-precaching, Anda bisa meneruskan alamat file dan string dengan informasi versi file-file ini ke metode pustaka precacheAndRoute() :

 import {preacacheAndRoute} from 'workbox-precaching'; precacheAndRoute([  {url: '/main.mjs', revision: '1a2b'},  {url: '/dep1.mjs', revision: 'b2c3'},  {url: '/dep2.mjs', revision: '3c4d'},  {url: '/dep3.mjs', revision: 'd4e5'},  {url: '/vendor.mjs', revision: '5e6f'}, ]); 

Bagaimana tepatnya menghasilkan garis dengan versi tergantung pada pengembang sendiri. Tetapi jika dia tidak ingin membuatnya sendiri, tugas membuat manifes pre-cache akan membantu menyederhanakan paket workbox-build , workbox-cli dan workbox-webpack-plugin (mereka bahkan dapat menghasilkan semua kode pekerja layanan).

Proyek demo saya memiliki contoh implementasi caching awal menggunakan pekerja layanan dalam aplikasi Rollup (menggunakan workbox-cli ) dan dalam aplikasi webpack (menggunakan workbox-webpack-plugin ).

Pendekatan # 3: skrip khusus untuk memuat sumber daya


Jika situs Anda tidak memiliki kemampuan untuk menggunakan kartu impor atau pekerja layanan, maka di sini adalah pendekatan ketiga untuk menyelesaikan masalah. Ini terdiri dalam mengimplementasikan fungsionalitas peta impor menggunakan skrip sendiri untuk memuat sumber daya.

Jika Anda terbiasa dengan pemuat modul gaya AMD (seperti SystemJS atau RequireJS ), maka Anda mungkin juga tahu bahwa pemuat modul ini biasanya mendukung alias modul. Bahkan, SystemJS mendukung aliasing menggunakan sintaks peta impor. Akibatnya, masalah kami mudah dipecahkan sedemikian rupa sehingga solusi ini akan berorientasi masa depan (dan, di samping itu, akan bekerja di semua browser yang ada).

Jika Anda menggunakan Rollup, maka Anda dapat mengatur opsi output.format ke system . Dalam hal ini, membuat peta impor untuk aplikasi akan dilakukan dengan cara yang sama seperti yang dijelaskan dalam deskripsi pendekatan pertama untuk memecahkan masalah pembatalan cache cascading.

Aplikasi demo saya memiliki contoh situs tempat Rollup digunakan untuk membangun materi dalam format yang cocok untuk SystemJS, dan untuk membuat peta impor untuk mengunduh versi file hash.

▍ Paket web dan memuat sumber daya menggunakan skrip


Webpack juga dapat membantu Anda memuat sumber daya menggunakan skrip Anda sendiri, tetapi loader yang dihasilkan oleh webpack, tidak seperti loader AMD klasik, unik untuk setiap bundel tertentu.

Keuntungan dari pendekatan ini adalah bahwa runtime webpack dapat (dan sebenarnya berfungsi) termasuk pemetaannya sendiri antara nama / pengidentifikasi fragmen dan alamatnya (ini mirip dengan apa yang saya rekomendasikan di sini). Ini berarti bahwa bundel webpack yang menggunakan pemecahan kode lebih kecil kemungkinannya menderita cascading cache invalidation.

Sebenarnya, kabar baiknya bagi pengguna webpack adalah jika mereka mengkonfigurasi dengan benar perakitan proyek menggunakan webpack (membagi kode menjadi fragmen, seperti yang dijelaskan dalam panduan caching webpack), maka perubahan dalam kode modul individual tidak boleh mengarah pada pembatalan. lebih dari dua fragmen (satu adalah yang berisi modul yang dimodifikasi, yang kedua adalah yang berisi runtime).

Tapi saya punya kabar buruk bagi mereka yang menggunakan webpack untuk membangun proyek. Faktanya adalah bahwa sistem pemetaan internal bundler ini tidak standar. Ini berarti bahwa itu tidak dapat diintegrasikan dengan alat yang ada, dan bahwa pengguna tidak dapat mengonfigurasinya. Misalnya, Anda tidak dapat menghasilkan file output secara mandiri (yaitu, lakukan seperti yang dijelaskan dalam cerita tentang pendekatan pertama untuk menyelesaikan masalah) dan masukkan hash Anda sendiri dalam pemetaan. Dan ini adalah minus dari webpack, karena hash yang digunakan oleh bundler ini tidak berdasarkan pada isi dari file output , tetapi pada isi dari file sumber dan pada konfigurasi build. Dan ini dapat menyebabkan kesalahan kecil dan halus (misalnya - di sini , di sini dan di sini - pesan tentang kesalahan tersebut).

Jika Anda menggunakan webpack untuk membangun aplikasi yang juga menggunakan pekerja layanan, maka saya akan merekomendasikan menggunakan workbox-webpack-plugin dan strategi caching, yang dijelaskan dalam pendekatan kedua untuk memecahkan masalah. Plugin akan menghasilkan hash berdasarkan konten output webpack, yang berarti Anda tidak perlu khawatir tentang kesalahan di atas. Selain itu, bekerja dengan nama file yang tidak memiliki hash biasanya lebih mudah daripada bekerja dengan nama yang memiliki hash.

Sumber daya proyek web lainnya


Sebelumnya, saya berbicara tentang bagaimana bekerja dalam program JavaScript dengan nama file "hash" yang berisi kode program dapat menyebabkan cascading invalidation cache. Tetapi masalah ini berlaku untuk materi proyek web lainnya.

Jadi, file CSS dan SVG sering merujuk ke sumber daya lain (gambar, misalnya), yang namanya mungkin berisi informasi tentang versi file yang sesuai dalam bentuk hash. Seperti dalam kasus file JS, untuk memecahkan masalah cascading invalidation cache yang disebabkan oleh perubahan nama sumber daya yang serupa, Anda dapat menggunakan kartu impor atau pekerja layanan.

Untuk sumber daya seperti file gambar dan video, ini tidak masalah. Semua rekomendasi yang ada berlaku di sini.

Hal utama di sini adalah untuk mengingat bahwa selalu, ketika file A mengunduh file B, dan, di samping itu, termasuk informasi tentang versi file B sebagai hash isinya, membatalkan cache untuk file B juga akan menyebabkan pembatalan cache untuk file A. bekerja dengan sumber daya, yang penggunaannya diatur secara berbeda, Anda bisa mengabaikan saran yang diberikan dalam materi ini.

Ringkasan


Saya harap artikel ini menginspirasi Anda untuk melihat lebih dekat pada situs Anda dan mencari tahu apakah masalah cascading cache invalidation memengaruhinya. Cara termudah untuk memeriksa ini adalah dengan merakit situs, mengubah satu baris kode dalam file yang diimpor oleh banyak modul, dan kemudian membangun kembali situs. Jika dalam direktori di mana hasil perakitan berada, nama-nama telah berubah untuk lebih dari satu file, ini berarti Anda memiliki tanda pembatalan cache cascading. Dan jika demikian, maka Anda mungkin perlu berpikir tentang menggunakan salah satu pendekatan yang dijelaskan di sini untuk menyelesaikan masalah ini dalam proyek Anda.

Jika kita berbicara tentang apa yang lebih baik untuk dipilih, maka, terus terang, itu tergantung banyak hal.

Ketika kartu impor akan didukung secara luas oleh peramban, maka kami akan menghadapi cara paling sederhana dan paling sempurna untuk menangani pembatalan cache berjenjang. Tetapi sampai dukungan tersebut tersedia, mekanisme ini tidak berlaku dalam praktiknya.

Jika Anda sudah menggunakan pekerja layanan, terutama jika Anda menggunakan Workbox, maka saya akan merekomendasikan pendekatan kedua untuk menyelesaikan masalah yang dibahas di sini. Di situs di mana materi asli ini diterbitkan, tugas caching awal sumber daya diselesaikan dengan cara ini.

Selain itu, pekerja layanan adalah satu-satunya pilihan bagi mereka yang menggunakan modul JavaScript dalam produksi. (Dan mengingat bahwa 98% pengguna saya memiliki browser yang mendukung baik pekerja layanan dan modul JS, tidak sulit bagi saya untuk memilih opsi ini).

Jika pekerja layanan tidak cocok untuk Anda, maka saya akan merekomendasikan ketiga pendekatan yang dibahas di sini, yang melibatkan penggunaan SystemJS. Pendekatan ini lebih baik daripada yang lain, berdasarkan skrip bootloader, berfokus pada masa depan. Dari sana akan mudah untuk beralih ke mengimpor kartu pada saat dukungan mereka akan muncul di semua browser.

Jika kita berbicara tentang produktivitas, maka pilihan arah pengoptimalannya bergantung pada setiap proyek tertentu. Sebelum mengoptimalkan kinerja, penting untuk mengukurnya, dan kemudian memutuskan apakah ada masalah, dan apakah perlu untuk menanganinya. Jika Anda jarang melepaskan rilis proyek baru, dan perubahan yang dibuat untuk proyek biasanya berskala cukup besar, maka masalah cascading cache invalidation mungkin tidak relevan bagi Anda.

Di sisi lain, jika Anda sering menggunakan perubahan proyek kecil, maka pengguna Anda yang kembali mungkin mengalami masalah memuat kode dalam jumlah besar yang sudah ada dalam cache mereka. Memecahkan masalah ini akan berarti peningkatan kinerja pemuatan halaman yang signifikan untuk pengguna tersebut.

Pembaca yang budiman! Apakah cascading invalidation cache memengaruhi proyek Anda? Jika demikian, beri tahu kami bagaimana Anda berencana untuk menyelesaikannya.


Source: https://habr.com/ru/post/id472862/


All Articles