vue server rendering add cache

Posted by Gabriel_Haukness on Tue, 31 Dec 2019 08:48:38 +0100

cache

Although the server-side rendering (SSR) of Vue is quite fast, due to the overhead of creating component instances and virtual DOM nodes, it cannot match the performance of pure string based templates. When SSR performance is critical, using cache strategy wisely can greatly improve response time and reduce server load.

 

vue service area cache is divided into page cache, build cache and interface cache

 

Page cache:

 

Set in server.js

const LRU = require('lru-cache')
const microCache = LRU({
  max: 100, // Maximum number of caches
  maxAge: 1000 // Important: entries expire in 1 second.
})

const isCacheable = req => {
  //Determine whether page caching is required
  if (req.url && req.url === '/') {
    return req.url
  } else {
   return false
  }
}
app.get('*', (req, res) => {
const cacheable = isCacheable(req)
  if (cacheable) {
    const hit = microCache.get(req.url)
     if (hit) {
      return res.end(hit)
  }
 }
const errorHandler = err => {
  if (err && err.code === 404) {
    // Page not found
    res.status(404).sendfile('public/404.html');
  } else {
    // Page rendering error
    res.status(500).end('500 - Internal Server Error')
    console.error(`error during render : ${req.url}`)
    console.error(err)
  }
}
const context = {
  title: 'vue',
  keywords: 'vue-ssr Service end scaffold',
  description: 'vue-ssr-template, vue-server-renderer',
  version: v,
  url: req.url,
  cookies: req.cookies
}
renderer.renderToString(context, (err, html) => {
  if (err) {
    return errorHandler(err)
  }
  res.end(html)
  microCache.set(req.url, html) // Set the content of the current cached page
})
})

  

Build cache:

 

The settings in server.js are as follows:

function createRenderer(bundle, template) {
  return require('vue-server-renderer').createBundleRenderer(bundle, {
    template,
    cache: LRU({
      max: 1000,
      maxAge: 1000 * 60 * 5 // Build cache time
    })
  })
}
let renderer
if (isProd) {
  // The production environment uses local packaging files for rendering
  const bundle = require('./output/vue-ssr-bundle.json')
  const template = fs.readFileSync(resolve('./output/index.html'), 'utf-8')
  renderer = createRenderer(bundle, template)
} else {
  // Development environment using web pack hot update service
  require('./build/dev-server')(app, (bundle, template) => {
    renderer = createRenderer(bundle, template)
  })
}

Build to cache

export default {
  name: 'Home',
  title() {
    return {
      title: 'vue-ssr',
      keywords: 'vue-ssr Service end scaffold, home',
      description: 'vue-ssr-template, vue-server-renderer, home'
    }
  },
  created() {
  },
  computed: {},
  asyncData({ store }) {},
  methods: {},
  serverCacheKey: props => props.id
}

The key returned by serverCacheKey should contain enough information to represent the specific situation of the rendering result. If the rendering result is only determined by props.item.id, then the above is a good implementation. However, if an item with the same ID may change over time, or if the rendering results depend on other props, you need to modify the implementation of serverCacheKey to consider other variables. If serverCacheKey returns a constant, the component will always be cached, which is good for static components.

 

Interface cache:

 

Set cache in create API server.js

import qs from 'qs'
import axios from 'axios'
import md5 from 'md5'
import LRU from 'lru-cache'
const microCache = LRU({ 
  max: 100,
  maxAge: 5000 // Set how long data expires
})
export function createAPI({baseUrl, timeout}) {
let api
if (process.__API__) { api = process.__API__ } else {
// Define the global variable process. API__ api = process.__API__ = { get(url, params = {}) { const key = md5(url + JSON.stringify(params)) // Judge whether there is a cache and return the cache result directly if (params.cache && microCache.get(key)) { console.log('Return cache') return Promise.resolve(microCache.get(key)) } return new Promise((resolve, reject) => { axios({ url, params, headers: { 'X-Requested-With': 'XMLHttpRequest' // 'Cookie': parseCookie(SSR.cookies) }, method: 'get' }).then(res => { // Determine whether cache is needed if cache data is needed if (params.cache && microCache) { microCache.set(key, res.data) } console.log('Return new data') resolve(res.data) }).catch(error => { reject(error) }) }) }, post(url, params = {}) { const key = md5(url + JSON.stringify(params)) // Judge whether there is a cache and return the cache result directly if (params.cache && microCache.get(key)) { return Promise.resolve(microCache.get(key)) } return new Promise((resolve, reject) => { axios({ url, data: qs.stringify(params), method: 'post', headers: { 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/x-www-form-urlencoded' // 'Cookie': parseCookie(SSR.cookies) } }).then(res => { // Determine whether cache is needed if cache data is needed if (params.cache && microCache) { microCache.set(key, res.data) } resolve(res.data) }).catch(error => { reject(error) }) }) } } }
return api
}

  

That's ok

Topics: Javascript Vue axios JSON hot update