查看原文:【技能分享】SSR办理方案探索
基于以往的utopia框架技能栈已经较为老旧,utopia-next的研发已经开始啦,本日给大家分享一下新一代utopia框架中ssr模块的采坑之路,分享之前先来一起理解下ssr的干系观点吧:
干系观点

SSR:做事端渲染(Server Side Render),DOM树在做事端天生后返回给前端,当前DOM树中的数据都已在做事端中天生,返回给浏览器进行渲染,传统的做事端渲染办法:PHP/JSP以及template + data => html + 前端jquery,这种办法通过原生的js去绑定dom事宜,部分代码无法在做事端实行,又称这是异构的做事渲染。
CSR:客户端渲染(Client Side Render),渲染过程交给浏览器处理,页面初始化加载的HTML中无内容,又嵌入的JS文件动态加载dom以及处理绑定事宜。
同构:指组件能在做事端运行,天生html,再由客户端React/Vue接管页面交互(事宜绑定)的做事端渲染办法。
在平时开拓中我们享受着当代框架(React/Vue)给我们带来的便利,选择做事端渲染办法也是如此,同构渲染能够带给我们更好的体验,当然,每种技能方案都有利有弊,我们来理解下同构渲染中须要考量的一些地方:
同构开拓的考量
1、前后端同构开拓对前端开拓者的心智哀求较高,不同于传统的spa开拓,做事端中获取数据的生命周期不同于客户端传统获取数据的生命周期,浏览器干系的接口无法在做事端中运行
2、繁芜的打包构建,须要单独的client打包与server打包
3、做事端负载,这也是传统SSR开拓的通病,当做事端压力较大时,做事端渲染能力也将受到影响,但同构的做事端渲染模式因其代码可以在客户端,做事端实行,可以做相对的转换,当做事器负载较高时,完备可以转为客户端渲染模式从而减轻做事端压力。
同构渲染的优点
1、更友好的SEO
2、更快的内容呈现
3、更优雅的渲染降级
4、做事端客户端代码共用
打包构建方案
传统的打包构建方案
利用webpack分别对客户端和做事端进行打包,做事真个包会被引入到做事端用来渲染html,同时客户真个包会被送到浏览器用于激活静态标记。
利用传统打包方案一贯以来都有一个痛点,那便是项目体历年夜了之后客户端打包较慢。
基于vite的打包方案
vite是一种新型前端构建工具,能够显著提升前端开拓体验
它基于原生ES模块供应了丰富的内建功能内置了rollup进行打包,可输出用于生产环境的高度优化过的静态资源vite的原生ES模块使你在开拓环境可以直接引入没有打包过的esmodule规范代码,极大程度得提升开拓环境的打包效率,但现版本的vite个人认为仍有部分须要考量。
1、对ssr的支持还在试验阶段。
2、rollup更适用于打库包而且不是须要更多代码分割处理的运用包
探索后的打包方案
基于传统SSR打包方按与vite打包方案的优缺陷,我们决定结合两者有点来实现新的打包方案:
1、利用vite办理传统打包方案中客户端打包较慢的痛点;
2、做事端还是webpack打包(做事端本身打包体量很小,打包速率上不会由于项目体量过大而有很不好的打包体验);
3、生产环境利用webpack5进行打包,webpack毕竟已经是老牌的打包工具,生态上更丰富,并且webpack5也引入了tree shaking支持。
详细实现
本地环境实行打包命令start,只会进行做事端打包;
生产环境实行打包命令build,进行客户端,做事端打包;
在做事端createSSRApp中嵌入vite的客户端热重载模块展开,同时我们将客户端入口文件经由vite处理过后引入到模板中,生产环境下客户端文件根据mainfest的映射依依引入。
大家可以看莅临盆环境下只引入了runtime~app.js,app.js,vendor.js文件,代码分割后的异步路由组件呢?
实际上异步组件通过webpack optimization处理过了,访问对应的路由会加载对应的文件,对应路由的js文件可以得到加载,但是在加载css文件的时候出了点问题,由于manifest天生的文件名是无规则的,我们并不清楚哪个路由该当引入哪个css,这时我们想到了webpack的webpackChunkName,我们通过一定的规则在路由里天生webpackChunkName,这样样式文件则通过当前路由下天生的webpackChunkName去manifest探求对应的css文件。
作为通用ssr办理方案,我们须要供应vite中间件处理。
不同的打包命令,实行不同的打经办法,不同的打经办法实行各自的打包配置。
前面说的做事端须要打包的体量很小,为什么做事端体量小?回到做事端渲染的初衷,做事端渲染最核心的是处理首页的seo问题,也便是说我们只须要处理首页的渲染即可,因此我们须要把一些不须要webpack处理的外部依赖项external掉,我们通过webpack-node-externals来实现它。
渲染降级
在做事端渲染与客户端渲染的选择上,我们供应了渲染降级的能力,而不是大略从脚手架触发去实现客户端渲染打包发布的版本和做事端渲染打包发布的版本。 再来看下做事端渲染和客户端渲染的差异:
客户端渲染:客户端再要求时,做事端不做任何处理,直接将原文件返回给客户端(这里一样平常值一个静态html),然后再由html中的javascript去天生DOM
做事端渲染:做事端在接到客户端要求后,获取要渲染页面所要的数据,然后构建DOM后拼接到返回客户真个模板之中。
什么情形下须要降级
做事端渲染时,我们常日会碰着这样的一种情形,有一个做事器负载压力相对较高的路由,当次路由访问流量较高或出于其他什么缘故原由导致报错时,该路由下渲染的模板返回也就会失落败,这个时候给用户的反馈上每每便是一个白屏或返回的缺点堆栈。
我们在做事端渲染出错时,回启用客户端渲染模式。
这样的降级处理不须要关心title,meta的部分,由于在我们的构造里layout部分始终是会渲染的,更换的仅仅只是children部分。
详细实现
我们供应了两种办法来降级处理:
1、在配置文件中定义renderMode,使全体系统利用csr渲染。
2、在要求中加入csr参数,可以使当前页面利用csr渲染模式。
处理完渲染的组件,再处理预处理数据,将本身在做事端渲染中的数据获取提到route中去实行。
这样我们便优雅得处理了渲染降级。
数据预获取
前面说的同构渲染要供应一个前后端都能实行其代码的能力,以是无论做事端渲染或者客户端渲染我们都供应数据预获取的能力,这样在渲染办法上才能自由切换并且不用耗费很大的心里,不用编写两套代码。
在SFC下我们供应了asyncData方法,该方法在做事端渲染时会在路由实行前完成,将获取到数据存储到pinia混入到客户端中去利用,同时在csr下,该方法会在route.vue挂载完成后去实行,并不会由于失落去做事端能力而无法实行。
Title、Mate处理
在title、mate、link等嵌入html标签上,我们供应了一个useMain文件去进行配置处理,该文件逻辑将会在骨架的setup中(created)去实行,useHtml中供应了做事端要求上线文,配置中央参数以便于动态去修正title数据。
useMain中返回的数据将直接渲染到骨架模板上。
由于骨架app.vue与路由route.vue没有对外暴露的缘故原由,以是我们通过useMain文件中的useComponent方法给用户供应全局注册组件、插件的处理,route.vue会在做事端客户端分别实行,因此不用再做事端客户端去分别注册。
Loading处理
由于做事端渲染的数据是在页面加载前去获取,因此在客户端路由跳转时获取数据会有一个短暂的白屏延迟,这样的体验是不好的,我们在客户端获取做事端数据的时候供应了一个loading页面去处理这个延迟,以便于见告用户目前正在加载数据,这个loading的状态的将有pinia去掌握,在项目中我们通过useCommonStore中的spining去掌握它。
我们默认为你供应了一个loading页,如果你有自定义的loading页将会覆盖我们为你供应的loading,但是你还是须要useCommonStore中的spining去掌握loading的状态。
UI库的处理
在做UI库的处理时,我们又碰着难题,若何在尽可能减少用户配置的条件下优雅的去处理按需导入,由于用户可能会利用各种不一样的UI库,如antv、element等,所有按需导入的配置也不一样,你可以选择在useMain中去全局导入,但我们不推举,由于在做事端渲染中UI库是须要被webpack处理的,因此为加入到打包,全局导入会严重拖慢做事端打包速率。
其余有种办法通过”babel-import-plugin“插件来实现按需导入,利用这种办法去处理的缺陷便是须要用户去配置各自UI库的动态导入。
后面我们找到了一种比较好的办法去处理按需导入,通过unplugin-vue-component和unplugin-auto-import去处理,定义知足此插件的UI列举(大多数高频利用的UI库都支持),通过配置ui库名字的办法去尽可能的减少配置量从而实现按需导入、自动导入。
我们定义了一个名叫“ui(AntDesignVue、ElementPlus、ElementUi、Vant、ViewUi...)”的配置变量,unplugin-vue-component支持webpack、vite等多种打包工具的支持,在webpack中通过ui去匹配对应的UI库处理插件。
至于vite中的配置由我们在跑命令的时候去动态天生,我们创建了一个vite.config.tpl模板,通过动态传入参数来天生vite配置文件,当存在该文件时将不会再天生,用户后续的配置可直接写在天生的vite.config.js文件上。
好啦,以上是我们探索的SSR办理方案,其余预报下,utopia-next即将与大家见面,敬请期待。
希望以上内容能对有须要的人有所帮助
欢迎大家一起磋商互换