近期比较忙,也遇到了很棘手的问题,vue ssr 内存泄漏,一直找不到问题根源,目前项目慢慢稳定下来,内存也维持在正常水平,通过alinode监测内存情况表现正常(由于我的服务器上部署了多个项目,维持在60%是正常状态):

img20170804175327.jpg

服务端渲染除了需要了解基本原理之外,需要特别注意性能问题,起初将doracms2.0部署到阿里云服务器上(内存1G),过了一晚上跑到300M,很明显的内存泄漏了,之前也有考虑过ssr是否适合内容比较多的应用,也有想过是否改架构,但作为vue ssr实践,有必要

去了解下哪些地方会引起内存问题。


1、合理使用缓存。vue ssr 官方案例中用到了lru-cache,以缓解性能方面的问题,要知道lru-cache缓存数据都是存内存的,需要合理使用,原则上讲缓存静态内容,经常变动频繁的内容最好不要缓存。


2、axios 的使用。axios 允许客户端和服务端发起请求,但是使用不当也会造成内存泄漏,在vue ssr项目中,可以考虑将axios封装一下,

针对不同环境进行调用,具体用法可以参考下面的文章。

Vue2 SSR 缓存 Api 数据


3、合理使用 v-once 。官网介绍如下:

只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。一般用在

渲染数据比较多的列表,而且内容不会经常变动。

<!-- 单个元素 -->
<span v-once>This will never change: {{msg}}</span>
<!-- 有子元素 -->
<div v-once>
  <h1>comment</h1>
  <p>{{msg}}</p>
</div>
<!-- 组件 -->
<my-component v-once :comment="msg"></my-component>
<!-- v-for 指令-->
<ul>
  <li v-for="i in list" v-once>{{i}}</li>
</ul>

我在几个组件用到了该标签:

header,footer,topicItem

<el-col v-for="(nav,index) in headerNav" :key="index" v-once>
     <router-link :to="{path: '/'+nav.defaultUrl+ '___'+nav._id}">{{nav.name}}</router-link>
</el-col>


4、合理使用keep-alive。主要用于保留组件状态或避免重新渲染。要知道,重复渲染数据量大的列表代价很大。


5、vue ssr 中的 runInNewContext 属性(2.3.1+)。官方解释非常详细了:

默认情况下,对于每次渲染,bundle renderer 将创建一个新的 V8 上下文并重新执行整个 bundle。这具有一些好处 - 例如,应用程序代码与服务器进程隔离,我们无需担心文档中提到的状态单例问题。然而,这种模式有一些相当大的性能开销,因为重新创建上下文并执行整个 bundle 还是相当昂贵的,特别是当应用很大的时候。 出于向后兼容的考虑,此选项默认为 true,但建议你尽可能使用 runInNewContext: false runInNewContext: 'once'


https://ssr.vuejs.org/zh/api.html#runinnewcontext