背景:
团队长久以来采用的工作模式都是后端返回一个vm,在vm里引用前端资源文件。当用户请求这个vm,通过在前端脚本异步获取数据来进行渲染。由于页面需要依赖数据来进行渲染,所以总是会有一段时间“白屏”。为了减少白屏的时间,我们采用的方案是页面先展示一个小骆驼loading图来缓解这种尴尬。但这仍然没有解决页面加载时间缓慢,用户体验不好的问题。
最近小半年来团队接了很多运营活动类推广页面。这类活动有个很鲜明的特点,页面简单,由广告媒体导流而来,追求页面渲染速度,你很难想象用户打开页面后,再花较长时间来等待内容的加载,可能在这段loading时间内用户就已经退出了活动页面,损失大量用户,而这些用户是公司花钱导流来的,市场同学肯定不满意。按照之前的模式,肯定达不到一个好的效果,怎么办?
服务端渲染这个概念很早就有,在后端jsp的天下时就是这么干的,那时各种拼接html操作。现在这个概念又被业界重新提了出来。网上有很多科普文和介绍实践的文章。这里只是简单mark下我自己的理解和工作中遇到的问题。
ssr
服务端渲染和浏览器渲染:
- 服务端提升渲染速度主要体现在服务端渲染减少了等待js加载和js数据请求这两个步骤,因此在首屏展示时间上大大缩短。同样是网络请求,后端发出和前端发出速度截然不同。后端明显更快。
- 原本的浏览器做的工作改由服务器做,会增加服务器的负载,增加cpu的压力。
- 要考虑容灾方案,万一服务端渲染失败可以切换到浏览器渲染。
在我读大学的时候,那时候刚接触到前端,脑子里以为前端的性能优化就是雅虎的那几条规则。随着工作经历的加深,越发感到当初的可笑。一个产品是通过一连串的环节来提供服务进行保障的。前端向前有客户端,向后有服务端。前端的性能优化早就不局限于自己的优化,还可以向两端扩展。服务端渲染就是当前端进入到后端领域后的一个自然的结果。
前端利用node来涉足到传统的后端领域,基于node做前后端分离,这已经不是一个新鲜的话题了。前端在后端的性能优化基于node可以做一些尝试:
- 简单的数据直出:现在如果用node实现一个服务器,node在返回vm的时候直接把数据也返给浏览器(比如直接挂在window上),这样浏览器就可以直接利用数据渲染,提高首屏渲染的速度,减少了请求数据的这部分时间。
- 服务端渲染:服务端直接返回已经拼接好的html片段,减少了浏览器拼接html的过程,这样会更快,特别适合那些简单的运营活动页。
- 服务端渲染,如果前后端代码可以复用,这就是前后端同构了。服务端和浏览器共用一套组件代码,实现渲染。
截止到目前,我们团队在部分业务中已经尝试了ssr。比如去哪儿App首页的发现频道,酒店宫格详情页底部更多入口,部分运营活动类页面都是通过ssr的方式渲染的。
要考虑的问题
- 如何打通公司现有的前端发布流程
- 设备嗅探。某些场景下页面渲染的效果需要依赖环境,但是服务端渲染时拿不到这些环境参数。解决办法:需要根据请求html时候携带的ua来提前做一些处理。
- 模块管理。前端使用的是es6 module。后端使用的是commonJS。node端如何引用ESModule定义的组件
- node如何接入传统后端RPC服务,比如java的dubbo
- 应用的健壮性,日志处理,监控报警,logstash + kibana
性能优化tips
- 模板缓存,不要每次都去硬盘读文件
- 路由查找,匹配正则路由和匹配字符串路由耗时不一致,字符串路由耗时更短
- 去除不必要的中间件,过多的中间件代表业务链路耗时更长
- ejs模板的include总是去硬盘里查找模板文件,优化点