找回密码
 会员注册
查看: 25|回复: 0

离线预渲染OPR:0成本接入媲美SSR效果

[复制链接]

3

主题

0

回帖

10

积分

新手上路

积分
10
发表于 2024-9-20 03:08:01 | 显示全部楼层 |阅读模式
关注我们文末有福利作者简介张所勇转转平台运营中心前端负责人,在前端领域有深入研究,包括:sketch一键切图、前端数据模型化,小程序基础能力建设等多个方面,10年工作经验中,做了2年工程师,5年CEO,3年技术管理,能写点文章,也是2018年度掘金优秀作者。细数现阶段业内首屏优化方案,主要有:SSR、Prerender、CSR等方案,这些方案的思路几乎都在于将渲染过程放到传统SPA用户端渲染之前,而传统性能优化手段在SPA项目上面收获甚微,原因在于SPA本身的致命缺陷:SPA方案在SPA项目的首屏性能上,我们在长期关注和不断探索,期间我们尝试过很多方案,包括:从减少代码体积角度的:webpack优化、打包优化、tree-shaking等从减少HTTP请求角度的:接口合并、按需加载、延时加载等各种方法减少请求从缓存角度出发:离线包、http&浏览器各种缓存使用、dns预解析、dll方案、接口缓存方案等从数据获取时机角度出发:webWorker预取数据、路由进入过程读取数据等从减少图片体积和数量出发:使用webp图片、请求域名并行优化、CSSSprite等这些方案都能一定程度上降低白屏时间和首屏时间,但收效有限,很难像SSR方案一样大幅降低数据,究其原因,SPA页面渲染过程如下:滑动查看图片从上图可以看到,白屏过程几乎是不可避免的,因为无论如何你去优化代码体积,Vue系列类库和你需要的其他核心类库文件加起来至少有几百K,在加上这些文件执行的时间(实测至少500ms),可能大多数情况,我们白屏时间至少1200ms-1500ms了。当然,我们可以把骨架屏所需的css放到HTML里面,能尽早的显示出骨架屏(但很多低版本内核需下载&执行完全部script后才会渲染页面),但这并非真正的首屏,即使在性能统计上,也无法直观反馈出首屏的提升。于是SSR方案成为我们的救命稻草:SSR方案我们再看下SSR如何解决这个问题:滑动查看图片SSR方案的优势在于,浏览器下载的HTML当中已经具备了首屏渲染所需的DOM结构和样式,白屏时间几乎等于HTML文件下载时间,而这个时间相比SPA已经很少了,性能数据有显著提升。那为什么我们不直接用SSR方案呢?主要原因有四点:1、SSR项目改造成本高Vue技术栈的SSR方案主流有两种:官方方案和Nuxt.js,这两种方案相同点都是:必须把现有webpack各项配置替换成上述两种方案工程工程所有页面都必须SSR方式的要求实现必须在自定义的asyncData/preFetch生命周期内获取数据必须将接口数据使用Vuex管理或许你认为这个也不难啊,对于一个新项目,确实不难,但对一个老项目来讲,上述的改造成本和测试成本就无比高了,这也是少有老项目改造SSR的原因。2、SSR性能依赖接口性能从SSR原理上你可以知道,SSR服务端渲染过程依赖于获取到全部数据才能开始渲染,一旦接口出现延时或超时,那首屏性能也会受到影响。3、SSR负载能力和扩容能力可能成为瓶颈几乎是业界公认,node的负载能力相比java等要差一些,相比nginx静态资源服务更差,并且很多公司在node服务器快速扩容上面,目前还没有太多实践和机制保障,虽然可以通过备足服务器来抵抗流量高峰,但毕竟这对应的是成本。4、SSR无降级方案一旦node服务故障,页面可能直接就会白屏,很多时候不是重启服务能够解决的,毕竟SSR不是像SPA一样在浏览器看见什么错误去解决或者回滚就可以的,你必须真正解决了故障才能恢复服务,这期间不能很容易的降级为SPA方案。上述原因当中,最主要阻碍我们用SSR的原因是改造成本。Prerender方案Prerender是基于prerender-spa-plugin这个webpack插件实现的,原理如下:滑动查看图片核心原理就是在webpack打包过程中,通过Puppeteer访问对应路由,抓取html并静态化,再部署cdn。但业内这种方案使用的比较少,主要原因有:静态化过程发生在构建环节,用户访问时看到的数据注定是过时的。这种方案依赖于使用history方式的路由,这对老项目的改造测试成本也不低。编译时间大幅增加,想想就知道啦。通过上述分析,我们能看出“最优方案”应该是SSR,不考虑负载能力的话,阻碍我们的只有改造成本了,能否用较低的成本实现跟SSR一样的效果呢?离线预渲染OPR晴空一声惊雷,OPR产生了,我们把他命名为离线预渲染OPR(OfflinePrerender)。OPR的渲染过程:滑动查看图片不同于SSR在用户访问阶段的渲染,OPR是一个独立于用户访问流程的渲染服务,它通过Puppeteer定期渲染页面并上传cdn,用户访问到的页面将会是纯静态页面,可以说是结合了SSR和Prerender两种方案。与SSR方案的区别:渲染过程独立于用户访问,没有服务器压力,占用资源极小,一台服务器即可完成页面几乎不需要任何改动渲染出来的页面效果几乎和SSR一致可降级为SPA方案与Prerender方案的区别:通过定时渲染,解决Prerender方案数据无法及时更新的问题页面几乎不需要任何改动对原本项目构架过程无任何影响OPR方案实现过程我们简单拆解来看:01定时访问页面我们首先搭建一个node服务,通过schedule机制定期通过Puppeteer访问需要渲染的页面。02等待页面渲染页面渲染是一个动态的过程,我们如何知道页面已经渲染完了呢,Puppeteer其实提供多种方案,但我们最终选用的方案是通过监听公司性能统计埋点发出时机,通过Puppeteer的page.waitForRequest方法可以很容易实现。03抓取HTML你必须清楚一点:我们抓取的是浏览器渲染的HTML,并非你请求到index.html文件内容。前者你可以理解为,通过浏览器开发者工具,选中html标签,右键拷贝outerHTML。后者你可以通过浏览器查看下html源码,里面应该只有空白的dom和一些
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 12:20 , Processed in 3.292191 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表