Caching penyemak imbas ialah arah penting dalam pengoptimuman bahagian hadapan Dengan menyimpan sumber statik, anda boleh mengurangkan masa memuatkan halaman, mengurangkan beban pelayan dan meningkatkan pengalaman pengguna. Artikel ini akan memperkenalkan prinsip asas caching penyemak imbas dan strategi caching biasa, dan melaksanakannya menggunakan kod di bawah rangka kerja koa nodejs.
Prinsip asas caching penyemak imbas adalah untuk cache sumber statik (seperti CSS, JavaScript, imej, dsb. .) Setempat, apabila halaman meminta sumber ini sekali lagi, ia diperoleh terus daripada setempat dan bukannya memuat turunnya dari pelayan sekali lagi. Ini boleh mengurangkan masa memuatkan halaman dan mengurangkan beban pelayan, meningkatkan pengalaman pengguna.
Dalam protokol HTTP, caching penyemak imbas boleh dilaksanakan melalui dua mekanisme: caching yang kuat dan caching yang dirundingkan. [Cadangan tutorial berkaitan: tutorial video nodejs]
Medan tamat tempoh:
Cache-Control (alternatif )
awam: Semua kandungan dicache (kedua-dua pelanggan dan pelayan proksi boleh dicache)
peribadi: Hanya dicache ke dalam cache peribadi ( Pelanggan )
tiada cache: Sahkan dengan pelayan sama ada respons yang dikembalikan telah ditukar sebelum menggunakan respons untuk memenuhi permintaan seterusnya untuk URL yang sama. Oleh itu, jika token pengesahan yang sesuai (ETag) hadir, tiada cache memulakan komunikasi pergi balik untuk mengesahkan respons yang dicache dan boleh mengelak daripada memuat turun jika sumber tidak diubah.
tiada kedai: Nilai tidak dicache
mesti-pengesahan/pengesahan-proksi: Jika kandungan yang dicache tidak sah, permintaan mesti dihantar ke pelayan Disahkan semula
max-age=xxx: kandungan cache akan tamat tempoh selepas xxx saat, pilihan ini hanya boleh digunakan dalam http1.1, adalah lebih baik daripada Ubahsuai terakhir Keutamaan lebih tinggi
Ubahsuai terakhir (tarikh terakhir diubah suai)
Ubahsuai terakhir: disimpan pada pelayan , rekod tarikh terakhir sumber diubah suai (tidak boleh tepat kepada saat, jika diubah suai beberapa kali dalam beberapa saat, ia boleh menyebabkan ralat untuk memukul cache)
if-modified-sejak: Simpan Dalam klien, permintaan dibawa dan dibandingkan dengan pelayan yang diubah suai Jika sama, cache akan dipukul terus dan kod status 304 akan dikembalikan 🎜>
const Koa = require('koa'); const app = new Koa(); // 设置 expires方案 const setExpires = async (ctx, next) => { // 设置缓存时间为 1 分钟 const expires = new Date(Date.now() + 60 * 1000); ctx.set('Expires', expires.toUTCString()); await next(); } // Cache-Control方案(优先执行) const setCacheControl = async (ctx, next) => { // 设置缓存时间为 1 分钟 ctx.set('Cache-Control', 'public, max-age=60'); await next(); } // Last-Modified方案 const setLastModified = async (ctx, next) => { // 获取资源最后修改时间 const lastModified = new Date('2021-03-05T00:00:00Z'); // 设置 Last-Modified 头 ctx.set('Last-Modified', lastModified.toUTCString()); await next(); } const response = (ctx) => { ctx.body = 'Hello World'; } // 跟Last-Modified方案相对应 const lastModifiedResponse = (ctx) => { // 如果资源已经修改过,则返回新的资源 if (ctx.headers['if-modified-since'] !== ctx.response.get('Last-Modified')) { response(ctx) } else ctx.status = 304; } app.get('/getMes', setExpires, response); app.listen(3000, () => console.log('Server started on port 3000'));
last-Modified: Disimpan dalam pelayan, merekodkan tarikh sumber terakhir diubah suai (tidak tepat kepada saat, jika ia diubah suai beberapa kali dalam beberapa saat, ia mungkin Menyebabkan ralat untuk memukul cache)
jika-diubah suai-sejak: Disimpan dalam klien, permintaan itu dibawa dan dibandingkan dengan yang terakhir- Diubah suai pada pelayan. Jika sama, cache terus dipukul dan kod status 304 dikembalikan
ETag boleh dijana menggunakan mana-mana algoritma, seperti pencincangan, manakala Terakhir Diubah Suai hanya boleh menggunakan format masa tertentu (GMT) . Perbandingan
ETag ialah pengesah padanan tepat dan memerlukan padanan tepat, manakala perbandingan Ubahsuai Terakhir adalah lemah. validator (pengesah lemah) hanya perlu sama dalam saat yang sama.
ETag sesuai untuk semua jenis sumber, manakala Terakhir Diubahsuai hanya sesuai untuk sumber yang jarang berubah, seperti gambar, video, dsb.
Untuk sumber yang kerap dikemas kini, ETag adalah lebih sesuai kerana ia dapat mengesan dengan lebih tepat sama ada sumber tersebut telah diubah suai manakala untuk sumber yang tidak dikemas kini dengan kerap, Last-Modified adalah lebih banyak sesuai kerana Ia mengurangkan beban pelayan dan trafik rangkaian. koa melaksanakan cache rundingan
koa menggunakan cincang untuk mengira nilai Etag:
const Koa = require('koa'); const app = new Koa(); // 设置 eTag方案 const setExpires = async (ctx, next) => { // 设置缓存时间为 1 分钟 const maxAge = 60; ctx.set('Cache-Control', `public, max-age=${maxAge}`); // 设置 ETag 头 const etag = 'etag-123456789'; ctx.set('ETag', etag); await next(); } // Last-Modified方案 const setLastModified = async (ctx, next) => { // 设置缓存时间为 1 分钟 const maxAge = 60; ctx.set('Cache-Control', `public, max-age=${maxAge}`); // 设置 Last-Modified 头 const lastModified = new Date('2021-03-05T00:00:00Z'); ctx.set('Last-Modified', lastModified.toUTCString()); await next(); } const response = (ctx) => { ctx.body = 'Hello World'; } // 跟Etag方案对应 const etagResponse = (ctx) => { // 如果 ETag 头未被修改,则返回 304 if (ctx.headers['if-none-match'] === ctx.response.get('ETag')) { ctx.status = 304; } else ctx.body = 'Hello World'; } // 跟Last-Modified方案相对应 const lastModifiedResponse = (ctx) => { // 如果资源已经修改过,则返回新的资源 if (ctx.headers['if-modified-since'] !== ctx.response.get('Last-Modified')) { response(ctx) } else ctx.status = 304; } app.get('/getMes', setExpires, response); app.listen(3000, () => console.log('Server started on port 3000'));
const Koa = require('koa'); const crypto = require('crypto'); const app = new Koa(); // 假设这是要缓存的资源 const content = 'Hello, world!'; app.use(async (ctx) => { // 计算资源的哈希值 const hash = crypto.createHash('md5').update(content).digest('hex'); // 设置 ETag 头 ctx.set('ETag', hash); // 判断客户端是否发送了 If-None-Match 头 const ifNoneMatch = ctx.get('If-None-Match'); if (ifNoneMatch === hash) { // 如果客户端发送了 If-None-Match 头,并且与当前资源的哈希值相同,则返回 304 Not Modified ctx.status = 304; } else { // 如果客户端没有发送 If-None-Match 头,或者与当前资源的哈希值不同,则返回新的资源 ctx.body = content; } }); app.listen(3000);
Pelayan mengembalikan kod status 304 jika cache tidak tidak sah dan pelanggan membaca data daripada cache
Jika cache tidak sah, sumber dan 200 kod status dikembalikan
Caching yang kuat biasanya menyimpan cache sumber statik (seperti CSS, JavaScript, imej, dll.) dalam penyemak imbas untuk mengurangkan masa memuatkan halaman dan mengurangkan beban pelayan.
Cache rundingan biasanya digunakan untuk cache sumber dinamik (seperti halaman HTML, data API, dll.) untuk mengurangkan beban pada pelayan dan penggunaan lebar jalur rangkaian.
Dalam aplikasi praktikal, caching kuat dan caching rundingan boleh digunakan secara bersendirian atau bersama-sama. Untuk sesetengah sumber statik, anda hanya boleh menggunakan caching yang kuat untuk beberapa sumber dinamik, anda hanya boleh menggunakan caching rundingan untuk beberapa sumber yang kerap berubah, anda boleh menggunakan caching yang kuat dan caching rundingan dalam kombinasi, yang boleh mengurangkan beban pada pelayan dan memastikan ketepatan masa.
Walaupun ia dilaksanakan menggunakan back-end nodejs, saya rasa front-end juga harus mengetahui lebih lanjut tentang pengetahuan ini supaya back-end boleh lebih baik untuk berinteraksi. Kita akan bercakap tentang bagaimana untuk melaksanakan bahagian hadapan nanti?
Untuk lebih banyak pengetahuan berkaitan nod, sila lawati: tutorial nodejs!
Atas ialah kandungan terperinci Apakah cache? Bagaimana untuk melaksanakannya menggunakan nod?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!