多层缓存协同工作流程 这三层缓存会像洋葱一样,从外到内,逐层保护您的应用: 第一层:CDN/浏览器缓存 (HTTP 缓存) - 最外层,离用户最近,也是最快的。 第二层:页面级缓存 (服务器内存) - 当CDN缓存未命中时,由您的服务器快速响应。 第三层:组件级缓存 (Vue SSR) - 当页面缓存也未命中时,在渲染新页面时尽可能复用组件,加快渲染速度。

多层缓存协同工作流程

这三层缓存会像洋葱一样,从外到内,逐层保护您的应用:

第一层:CDN/浏览器缓存 (HTTP 缓存) - 最外层,离用户最近,也是最快的。

第二层:页面级缓存 (服务器内存) - 当CDN缓存未命中时,由您的服务器快速响应。

第三层:组件级缓存 (Vue SSR) - 当页面缓存也未命中时,在渲染新页面时尽可能复用组件,加快渲染速度。

const Koa = require('koa');const path = require('path');const Router = require('koa-router');const {
  createBundleRenderer
} = require('vue-server-renderer');const {
  LRUCache
} = require('lru-cache'); // 引入 lru-cache

// --- 1. 初始化所有缓存实1例 ---

// a. 用于组件级缓存const componentCache = new LRUCache({max: 1000,ttl: 1000 * 60 * 5, // 缓存5分钟});

// b. 用于页面级缓存const pageCache = new LRUCache({max: 100,ttl: 1000 * 60, // 缓存1分钟});

// ... (devConfig, PORT, app, router 等初始化) ...const devConfig = require('./build/dev.config.js');const PORT = 3003;let renderer;const app = new Koa();const router = new Router();

// --- 2. 注入组件级缓存 ---const createRenderer = (bundle, options) => {
  renderer = createBundleRenderer(
    bundle,
    Object.assign(options, {
      runInNewContext: false,
      cache: componentCache, // 注入组件缓存
    }));};

if (process.env.NODE_ENV === 'production') {const template = require('fs').readFileSync('./src/index.template.html', 'utf-8');const serverBundle = require('./dist/vue-ssr-server-bundle.json');const clientManifest = require('./dist/vue-ssr-client-manifest.json');createRenderer(serverBundle, {
    template,
    clientManifest,});} else {const template = path.resolve(__dirname, './src/index.template.html');devConfig(app, template, (bundle, options) => {
    createRenderer(bundle, options);});}// --- 3. 实现页面缓存和HTTP缓存头的中间件 ---const render = async (ctx, next) => {const url = ctx.url;

  // 设置HTTP缓存头,对所有请求生效// public: 响应可以被CDN等中间缓存存储// max-age=300: 缓存有效期5分钟
  ctx.set('Cache-Control', 'public, max-age=300');

  // 检查页面缓存const cachedPage = pageCache.get(url);if (cachedPage) {
    console.log(`[Page Cache HIT] for ${url}`);
    ctx.set('Content-Type', 'text/html');
    ctx.body = cachedPage;
    return next();}
  console.log(`[Page Cache MISS] for ${url}`);

  // 页面缓存未命中,执行渲染
  ctx.set('Content-Type', 'text/html');const context = {
    url: url,
    title: '服务端渲染',
    meta: `
      
      
    `,};

  try {
    // 调用 renderToString 时,组件级缓存会自动生效
    const html = await renderer.renderToString(context);
    ctx.body = html;
    // 将新渲染的页面存入缓存
    pageCache.set(url, html);} catch (err) {
    console.log(err);
    ctx.status = 500;
    ctx.body = 'Internal Server Error';}next();};

router.get('*', render);

app.use(router.routes()).use(router.allowedMethods());

app.listen(PORT, () => {
  console.log(`server started at http://localhost:${PORT}`);});


暂无评论