性能优化,这是面试中常常会聊到的话题。我以为性能优化应该因具体场景而异,因不一样项目而异,不一样的手段不一样的方案并不必定适合全部项目,固然这其中不乏一些普适的方案,好比耳熟能详的文件压缩,文件缓存,CDN,DNS 预解析,等等,可是我更但愿听到的是由于不一样的项目不一样的需求,解决不一样的问题而采起的不一样的优化手段,好比 BigPipe,分段输出页面的各个部分,对于 SNS 网站是很是合适的,减小了用户的等待时间;相对应的还有一个 BigRender,这是一个大的延迟加载,360 导航首页目前还在使用,京东淘宝首页也是这个思路,对于一些类门户网站很是适用,可是若是你的网页内容不是很是多,就没有必要了html
今天要说的是 Nuxt。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 性能确实不乐观,我测试了官网的 hackernews demo 项目,2 核 cpu + 4g 内存,400 并发下它的吞吐量不超过 50,就算是最简的 Nuxt 项目,吞吐量也就 300+,这就说明若是项目不作缓存,300+ 已是最大的吞吐量了,而最小 express demo 能够轻松到 3000,这就决定了高流量项目并不会轻易去使用 Nuxtwebpack
咱们的项目目前实际上是一个不加优化的 Nuxt 项目,由于用户很少,平时并无什么问题,可是一到展会,就会有很多用户同时访问,反馈页面会很卡。同条件下作了压测后,吞吐量也是 50 上下,平均响应时长七八秒,因此卡是正常现象web
看了一下项目代码,发现了几个问题:面试
对此我以为能够从两个方向去优化:express
缓存。缓存是最重要的方案,针对 Nuxt 项目能够作三级缓存,页面缓存、组件缓存以及 API 缓存。页面缓存是最重量级的缓存方案,能不能作页面缓存能够从如下两个点判断:浏览器
其实也就是返回的 html 代码相同就好,主要关注下返回的全局 store 是否一致,另外也不能作一些服务端才能作的操做,好比 set-cookie 等缓存
控制好首屏模块个数,对返回的结果进行精简,最小化,保证吐出到浏览器的内容足够小。这就是前面说的并不要对全部模块都作 ssr,须要首屏呈现的/须要爬虫爬的,咱们直出,其余部分作 CSR 就好了性能优化
而咱们的网站大部分页面是知足作页面缓存条件的,测试了下若是作页面缓存,吞吐量能到 500+,这个数据这个时候实际上是和页面大小有关系了,页面缓存的性能是能知足需求的。而有另外一类页面,相同的 URL 会返回不一样的内容,并且整页都是不一样内容,它的实现是获取 cookie 中的不一样 city-id,渲染不一样城市的内容,很显然这部分页面作不了页面缓存了,API 缓存和组件缓存理论上都是能够试试的cookie
作缓存优化,至少须要访问一次,第二次才能生效,那么还有另外一种状况,对于这样的路由 /store/:id
,并发打开 id 0~1000,很显然每一个页面都是不同的店铺数据,并不能命中缓存(可能命中组件缓存,暂时忽略),这个时候只能从 Nuxt 生命周期上去优化了,那么以上方向的第二点,控制首屏模块个数就能用到了。因此本文一开始我就说,不一样的方案是适配不一样的场景的,解决不一样的问题会采起不一样的手段