Nuxt笔记

383 阅读3分钟

这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

简介

Nuxt 是支持 Vue SSR 的一个框架,底层需要运行 Node 服务。大概描述一下 Vue 的渲染过程,首先每个组件都会被编译生成一个渲染函数(这部分基本 webpack 打包已经做掉),然后渲染函数生成虚拟 dom,最后虚拟 dom 通过 patch 方法将真实 dom 渲染到页面上。Nuxt 其实就是将这部分放到了服务端去做,在服务端拿到渲染页面所需要的 html,从而使得 html 能够直出,而客户端其实还是会运行整个 Vue 的生命周期,这就带来了一个问题,这部分操作放在了服务端其实是非常耗 cpu 的,创建组件实例和虚拟 DOM 节点的开销,无法与纯基于字符串拼接的模版的性能相当,如果是不加优化的 Nuxt 项目,高并发下是很脆弱的,毕竟 Node 运行在单线程下,不适合 cpu 操作密集型的场景

使用 Nuxt 的项目无非看中了它的两大优点,一是服务端渲染满足 SEO 的需求,二是首屏直出比 SPA 快,再加上如果如果公司是 Vue 系,使用 Nuxt 就更顺理成章。但是不要忘了性能,高并发下 Nuxt 性能确实不乐观,就算是最简的 Nuxt 项目,吞吐量也就 300+,这就说明如果项目不做缓存,300+ 已经是最大的吞吐量了,而最小 express demo 可以轻松到 3000,这就决定了高流量项目并不会轻易去使用 Nuxt

优化方向

缓存

缓存是最重要的方案,针对 Nuxt 项目可以做三级缓存,页面缓存、组件缓存以及 API 缓存。页面缓存是最重量级的缓存方案,能不能做页面缓存可以从以下两个点判断:

  • 同一个 URL,对于 登录 / 非登录 用户,服务端渲染的内容是相同的(注意是服务端渲染内容,而非前端)
  • 同一个 URL,对于不同的登录用户,服务端渲染的内容是相同的,即没有一些个性化的渲染(常见的个性化渲染,比如针对不同用户渲染不同的猜你喜欢内容等)

其实也就是返回的 html 代码相同就好,主要关注下返回的全局 store 是否一致,另外也不能做一些服务端才能做的操作,比如 set-cookie 等

控制好首屏模块个数

对返回的结果进行精简,最小化,保证吐出到浏览器的内容足够小。这就是前面说的并不要对所有模块都做 ssr,需要首屏呈现的/需要爬虫爬的,我们直出

不必要的渲染开销

服务端渲染最主要的作用是 seo,但并不是所有的页面都需要进行 seo。整站式的 ssr 意味着将消耗巨大服务器 cpu 资源,如果只从后端渲染需要 seo 的页面,将极大的节省 cpu 资源,空余出来的 cpu 资源则作用于更大的并发量。例如:掘金 就仅仅是在文章的详情页做 ssr 。

在不需要的组件外括上使用client-only  标签

踩坑

v2-fd985d5463f679262d650a3c9bf1ce03_720w

问题原因:当我们用SSR模式中,组件用v-if="API取得的值"的话,这个组件在一开始在服务器端(SSR)是不会被创建的,然后客户端(CSR)激活的时候由于拿到API数据导致这个组件为true,就产生了错误。(然后还被重复请求了三次,导致之后所有的界面都受牵连)所以用v-show的话,会在服务器端生成一个空的组件来占位,然后等客户端渲染的时候就自然而然出现了。

解决方法:用的v-if="API取得的值"改成了v-show就可以了。