本文为原创文章,引用请注明出处,欢迎大家收藏和分享💐💐
如今的前端技术层出不穷,无论是react
、vue
等框架还是跨端解决方案,为使用场景和开发效率做了不少的提升,但作为前端技术的重要衡量指标之一,首屏渲染效率无疑前端老生常谈的话题了。这篇文章就来聊下如何在常见的H5环境下,做到页面秒开。
这里也是引用笔者之前做过的一个业务来举例:有一个模拟用户朋友圈记录的H5页面,用户能通过管理端来编辑一条朋友圈消息「图文|视频」,并展示在这个H5页面上。如下图:
在这个场景下,如何快速打开页面并把朋友圈动态展示出来就显得尤为重要了,因为首屏速度越快,有效曝光率就越高、挽留率也就越高,如何提高页面的访问速度可以说是这个业务的硬性指标。
另外,这个业务还有另外的技术要求:
在确定方案前,我们先回顾下网页的请求全流程:
DOM Tree
;CSSOM
;RenderTree
;Javascript
代码有权利改变DOM树;由此看来,对于首屏的常规优化,我们可以采取资源压缩&合并、cdn加速、骨架图等一系列措施,这都是老生常谈的优化方案了;
其实,对于动态页面,往往需要在onload后发起额外的异步请求(上述第6步),在这个过程中,会有或多或少的等待时间,降低用户体验。
思考:有没有办法让这类页面提前渲染出最终形态??
没错,我们可以采用ssr渲染方案(即是在part1过程进行数据提前处理),在请求html的时候在网关层进行拦截,转发到后台服务把数据写入html,把最终带有数据的页面返回给前端,流程图如下:
这是常规的SSR渲染方案,只是异步数据拉取时机由前端调用改为服务端调用。按理说,这时候的:首屏时长=服务请求时长+服务获取异步数据时长+浏览器渲染页面时长。
虽然说服务器拉数据比前端更稳定和快速,但带来了额外的问题:
拉取数据服务宕机,导致html请求阻塞,前端页面一直处于空白等待状态,需要服务端做额外逻辑兼容; 拉取数据耗时较长时,前端页面的白屏时间也相应增加,不但没有实现秒开效果,反而拖慢页面加载速度;
思考plus:有没有办法在实现SSR情况下又能保证页面秒开?
这样,我们再想想在哪个流程点可以优化下:
缺点:无法抹平异步数据加载带来的页面抖动,但可以快速给用户呈现页面雏形,综合考虑无法满足需求,舍弃。
使用localstorage对首次请求得到的数据缓存,并设置有效时间,在有效期内直接读取本地数据...
缺点:无法保证数据实时性,无法满足需求,舍弃。
这个就是在服务器拉取数据时加上短暂的时间判断,在接口超时情况下直接返回没有ssr渲染的页面,前端在首屏完成后再异步请求数据。
分析:服务器之间的请求相对比较稳定而高效,ssr成功率也相对比较高,可以采取。
改后的流程如下:
这方案大致思路:admin在管理后台新增朋友圈记录时,顺便拉取该用户最近20条记录,并把它们写进redis中。之后在H5请求数据时,先进redis检查是否有用户记录,有就直接写ssr并返回document,达到极速渲染效果。
一般对于数据量不是很大的请求,http在跨服务上的请求平均耗时100+ms起,而redis能达到10+ms的级别,在这2种方式,效率差别尤为明显。
技术栈:nodejs、react、redis、ReactDOMServer
整理后的流程如下:
redis具备高性能的特点,参考资料《redis高性能原理》 ReactDOMServer可以参考官方描述,主要作用是在服务端将react函数实例化成一个dom
对于异步获取数据的http请求开销:
使用nodejs+redis ssr处理耗时:
{"msg":"开始处理demo_user的ssr渲染...","time":"2021-04-11T03:36:45.842Z","v":0}
{"msg":"redis数据读取成功,共20条数据","time":"2021-04-11T03:36:45.858Z","v":0}
{"msg":"ssr渲染处理成功","time":"2021-04-11T03:36:45.869Z","v":0}
浏览器视角,获取html文档流开销:
整个数据获取+处理过程大约只需要27ms,而首屏完全加载时间也保证在329ms,对比起来,我们在请求html文档时,在服务器直接对redis读取数据并写入ssr,效率提高了不止一个档次。
那如何保证redis数据是最新的?其实也很简单,在对用户数据进行数据库操作同时,更新一份到redis就可以了,而且ssr用于首屏渲染只需要前20条数据,固redis保存的数据量是可控的。当然,redis也不是绝对可靠的,所以我们还需要做些补偿方案,例如在redis获取数据失败时,改调用接口获取数据等。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。