转载

Vue2 SSR 渲染的优化之旅

自从 Vue2 出正式版后, 就开始了 SSR 之旅, 不过之前用的都是虚拟主机, 部署不了 SSR, 所以也只是在本地写着玩, 双 11 的时候, 买了个某云主机, 正式开始了 SSR 之旅, 然后过程并不顺利, 部署, 运行都没问题, 但是发现内存泄漏严重, 1核1G内存的主机根本负担不了, 没什么访问量的情况下, 几个小时的时间, 1G 内存就用光, 明显有很严重的内存泄漏, 在本地环境压测, rps(每秒请求数) 无限接近于 1, 在云服务器更是压测都完成不了, 于是开始了优化之旅

1. 内存泄漏

经过查资料和测试, 发现 axios 和 vue-meta 都有内存泄漏之嫌

vue-meta

之前有写过一篇 Vue2 SSR渲染, 如何根据不同页面修改 meta? , 既然这个有内存泄漏的嫌疑, 只好先把代码恢复回去

axios

axios 的拦截器在 node 端也会导致内存泄漏, 因为之前版本是 SPA 版的, axios 配置也是针对 SPA 的配置, 里面有用到拦截器, 并且有大量的逻辑处理在里面, 包括加载进度, 错误处理等等, 这些逻辑在 node 端是没有任何意义的, 那么我们就需要对 node 端写个专门的 axios 配置文件

  • api/index-server.js (server端)

    https://github.com/lincenying...
  • api/index-client.js (client端)

    https://github.com/lincenying...

2. 缓存

缓存主要包括两个部分:

  • 服务端的 api 数据缓存

  • 组件的缓存

服务端的 api 数据缓存

昨天已经写了一篇文章: Vue2 SSR 缓存 Api 数据 , 这里不再多说, 上面 axios 服务端配置文件中, 也有相关代码

组件的缓存

首先先安装 lru-cache
然后在 server.jscreateBundleRenderer 的时候带上缓存的配置

require('vue-server-renderer').createBundleRenderer(bundle, {
    cache: require('lru-cache')({
        max: 1000, // 缓存最大数量
        maxAge: 1000 * 60 * 15, // 缓存时间 15分钟
    })
})

在组件里申明 key

serverCacheKey: () => {
    return `aside::account`
}

组件缓存的相关用法, 请参考官方文档:

https://github.com/vuejs/vue/...

注意: 一般情况下, 我们不要给容器型组件, 只给展示型组件加缓存, 如一个组件是静态组件, 如组件的数据是通过 props 传进去的

3. 配置 nginx

一般情况我们都需要用 nginx 或者 apache 做端口转发,

server {
    listen 80;
    server_name mmxiaowu.com www.mmxiaowu.com ssr.mmxiaowu.com;
    location / {
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host  $http_host;
         proxy_set_header X-Nginx-Proxy true;
         proxy_set_header Connection "";
         proxy_pass http://127.0.0.1:8080;
    }
}

我们可以修改下配置文件, 让静态文件直接走 nginx, 不再经过 nodejs

server {
    listen 80;
    server_name mmxiaowu.com www.mmxiaowu.com ssr.mmxiaowu.com;
    location ~ ^/(static|upload)/  {
         root /your/webroot/mmf-blog-vue2-ssr/dist;
         expires 30d;
    }
    location / {
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host  $http_host;
         proxy_set_header X-Nginx-Proxy true;
         proxy_set_header Connection "";
         proxy_pass http://127.0.0.1:8080;
    }
}

经过以上一些优化后, 再进行一次压测:

E:/web/webpack/mmf-blog-vue2-ssr>loadtest -n 2000 http://localhost:8080/
[Sat Dec 31 2016 14:12:17] INFO Requests: 0 (0%), requests per second: 0, mean latency: 0 ms
[Sat Dec 31 2016 14:12:22] INFO Requests: 246 (12%), requests per second: 49, mean latency: 20.3 ms
[Sat Dec 31 2016 14:12:27] INFO Requests: 508 (25%), requests per second: 52, mean latency: 19 ms
[Sat Dec 31 2016 14:12:32] INFO Requests: 773 (39%), requests per second: 53, mean latency: 18.8 ms
[Sat Dec 31 2016 14:12:37] INFO Requests: 1036 (52%), requests per second: 53, mean latency: 19 ms
[Sat Dec 31 2016 14:12:42] INFO Requests: 1296 (65%), requests per second: 52, mean latency: 19.2 ms
[Sat Dec 31 2016 14:12:47] INFO Requests: 1548 (77%), requests per second: 50, mean latency: 19.9 ms
[Sat Dec 31 2016 14:12:52] INFO Requests: 1776 (89%), requests per second: 46, mean latency: 21.8 ms
[Sat Dec 31 2016 14:12:57] INFO
[Sat Dec 31 2016 14:12:57] INFO Target URL:          http://localhost:8080/
[Sat Dec 31 2016 14:12:57] INFO Max requests:        2000
[Sat Dec 31 2016 14:12:57] INFO Concurrency level:   1
[Sat Dec 31 2016 14:12:57] INFO Agent:               none
[Sat Dec 31 2016 14:12:57] INFO
[Sat Dec 31 2016 14:12:57] INFO Completed requests:  2000
[Sat Dec 31 2016 14:12:57] INFO Total errors:        0
[Sat Dec 31 2016 14:12:57] INFO Total time:          39.933183222 s
[Sat Dec 31 2016 14:12:57] INFO Requests per second: 50
[Sat Dec 31 2016 14:12:57] INFO Mean latency:        19.9 ms
[Sat Dec 31 2016 14:12:57] INFO
[Sat Dec 31 2016 14:12:57] INFO Percentage of the requests served within a certain time
[Sat Dec 31 2016 14:12:57] INFO   50%      16 ms
[Sat Dec 31 2016 14:12:57] INFO   90%      27 ms
[Sat Dec 31 2016 14:12:57] INFO   95%      43 ms
[Sat Dec 31 2016 14:12:57] INFO   99%      57 ms
[Sat Dec 31 2016 14:12:57] INFO  100%      133 ms (longest request)

Vue2 SSR 渲染的优化之旅

效果非常不错, rps 已经能达到 50 了, 内存使用也大弧度下降了, 不过在云服务器上依然不够理想, 因为可能是云服务器上数据比本地的多, 另外云服务器的配置太烂...但是随着运行时间的增加, 内存肯定也会上升, 毕竟缓存也是需要占用内存的, 不过这个是属于合理开支...

Vue2 SSR 渲染的优化之旅

过了差不多一天的时间, 内存只涨了 7M 左右...

原文  https://segmentfault.com/a/1190000007985486
正文到此结束
Loading...