Rumah  >  Artikel  >  hujung hadapan web  >  Apakah cache? Bagaimana untuk melaksanakannya menggunakan nod?

Apakah cache? Bagaimana untuk melaksanakannya menggunakan nod?

青灯夜游
青灯夜游ke hadapan
2023-03-06 19:33:582641semak imbas

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.

Apakah cache? Bagaimana untuk melaksanakannya menggunakan nod?

Prinsip Caching

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]

Cache kuat

  • Medan tamat tempoh:

    • Nilai ialah masa tamat yang dikembalikan oleh pelayan, yang mungkin menyebabkan ralat hit cache disebabkan oleh masa yang berbeza antara pelayan dan klien
  • 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 🎜>

  • Cache rundingan (pelayar dan pelayan berunding dan menilai mengikut nilai)

Etag/if-None - Padankan
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'));

Etag: Pelayan mengira nilai cincang (juga boleh menjadi algoritma lain, mewakili pengecam sumber) ​​

berdasarkan sumber yang diminta dan mengembalikannya ke penyemak imbas seterusnya masa Apabila penyemak imbas meminta sumber, ia menghantar Etag ke pelayan melalui medan if-None-Match
    Last_Modified dan if-Modified-Sejak

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

    • Rundingkan perbezaan antara ETag cache dan. Terakhir Diubah Suai:

ETag

ialah pengecam unik yang diberikan kepada sumber oleh pelayan dan Terakhir Diubahsuai ialah masa terakhir diubah suai sumber seperti yang dilaporkan oleh pelayan.

  • 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:

Proses pelaksanaan cache:
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'));

Cache yang kuat tidak sah, data dibaca daripada cache, keutamaan kawalan cache lebih tinggi daripada Diubahsuai terakhir
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);

Cache kuat gagal, cache rundingan dilaksanakan dan keutamaan Etag akan lebih tinggi daripada Last-Modified

  • 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

  • Penggunaan cache yang kuat dan cache yang dirundingkan?

    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.

    Kesimpulan

    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!

    Kenyataan:
    Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam