vue-ssr性能优化几种方法

vue-ssr性能优化:

  • 减少服务端渲染DOM数:

    • 1.结合vue的插槽系统、内置component组件的is,利用vue ssr服务端只会执行beforeCreate和created生命周期的特性,封装自定义组件,该组件在mounted的时候将包裹的组件挂载到component组件的js属性上。
    • 2.vue高级异步组件封装延迟加载方法,只有当模块到达指定可视区域时在加载。
  • 开启多进程。node.js是单进程,单线程模型。

  • 开启缓存:

    • 1.页面级缓存:在创建render实例时利用LRU-Cache来缓存当前请求的资源。
      附上我这边的代码吧,比较懒,全粘贴上去了哈哈哈:
const fs = require('fs')
const path = require('path')
const LRU = require('lru-cache')
const express = require('express')
const favicon = require('serve-favicon')
const compression = require('compression')
const microcache = require('route-cache')
const resolve = file => path.resolve(__dirname, file)
const {
      createBundleRenderer } = require('vue-server-renderer')

const isProd = process.env.NODE_ENV === 'production'
const useMicroCache = process.env.MICRO_CACHE !== 'false'
const serverInfo =
  `express/${
       require('express/package.json').version} ` + 
  `vue-server-renderer/${
       require('vue-server-renderer/package.json').version} `

const app = express()

function createRenderer(bundle, options) {
     
  return createBundleRenderer(bundle, Object.assign(options, {
     
    // 组件级别缓存
    cache: LRU({
     
      max: 1000,
      maxAge: 1000 * 60 * 15
    }),
    basedir: resolve('./dist'),
    runInNewContext: false
  }))
}

let renderer
let readyPromise
const templatePath = resolve('./src/index.html')

if(isProd) {
     

  const template = fs.readFileSync(templatePath, 'utf-8')
  const bundle = require('./dist/vue-ssr-server-bundle.json')

  const clientManifest = require('./dist/vue-ssr-client-manifest.json')
  renderer = createRenderer(bundle, {
     
    template,
    clientManifest
  })
} else {
     
  readyPromise = require('./build/setup-dev-server')(
    app,
    templatePath,
    (bundle, options) => {
     
      renderer = createRenderer(bundle, options)
    }
  )
}

const serve = (path, cache) => express.static(resolve(path), {
     
  maxAge: cache && isProd ? 1000 * 60 * 60 * 24 *30 : 0
})

app.use(compression({
      threshold: 0 }))
app.use(favicon('./public/logo.png'))
app.use('/dist', serve('./dist', true))
app.use('/public', serve('./public', true))
app.use('/manifest.json', serve('./manifest.json', true))

app.use(microcache.cacheSeconds(1, req => useMicroCache && req.originalUrl))

function render(req, res) {
     
  const s = Date.now()

  res.setHeader("Content-Type", "text/html")
  res.setHeader("Server", serverInfo)

  const handleError = err => {
     
    if(err.url) {
     
      res.redirect(err.url)
    } else if(err.code === 404) {
     
      res.status(404).send('404 | Page Not Found')
    } else {
     
      res.status(500).send('500 | Internal Server Error')
      console.error(`error during render : ${
       req.url}`)
      console.error(err.stack)
    } 
  }

  const context = {
     
    title: 'SSR-hahahahahha',  // default title
    meta: `
      
    `,
    url: req.url
  }

  renderer.renderToString(context, (err, html) => {
     
    if(err) {
     
      return handleError(err)
    }
    res.send(html)
    if(!isProd) {
     
      console.log(`whole request: ${
       Date.now() - s} ms`)
    }
  })
}

app.get('*', isProd ? render : (req, res) => {
     
  readyPromise.then(() => render(req, res))
})

app.listen(8000,()=>{
     
  console.log("server running at http://127.0.0.1:8000")
})


// app.set('port', process.env.PORT || 8888)
// let hostname = '0.0.0.0'
// app.listen(app.get('port'), hostname, () => {
     
//   console.log(`Server running at http://${hostname}:${app.get('port')}`)
// })

  • 2.组件级缓存:可缓存组件必须定义一个唯一的name选项。通过使用唯一的名称,每个缓存键cache key对应一个组件。如果render在组件渲染过程中进行缓存命中,那么它将直接重新使用整个子树的缓存结果。
  • 3.分布式缓存:SSR应用程序部署在多服务、多进程下,进程下的缓存并不是共享的,造成缓存命中率低下。可以采用如redis,用以实现多进程间对缓存的共享。

参考文章:SSR同构降级策略

你可能感兴趣的:(性能优化,Vue)