ssr源代码(SSR和前端编译在这点上是一样的)
ssr源代码(SSR和前端编译在这点上是一样的)
2024-09-29 10:27:40  作者:俄式爷们儿  网址:https://m.xinb2b.cn/sport/irc335781.html

我们通过组件的方式来开发前端页面,在浏览器里面,组件渲染时会通过 dom api 对 dom 做增删改来显示相应的内容但在服务端并没有 dom api,我们可以把组件渲染成 html 字符串,然后下发到浏览器渲染,因为已经有了 html 了,就可以直接渲染成 dom,不再需要执行 JS,所以很快,接下来我们就来聊聊关于ssr源代码?以下内容大家不妨参考一二希望能帮到您!


ssr源代码

我们通过组件的方式来开发前端页面,在浏览器里面,组件渲染时会通过 dom api 对 dom 做增删改来显示相应的内容。但在服务端并没有 dom api,我们可以把组件渲染成 html 字符串,然后下发到浏览器渲染,因为已经有了 html 了,就可以直接渲染成 dom,不再需要执行 JS,所以很快。

第一种浏览器渲染的方式叫做 CSR (client side render),第二种服务端渲染的方式叫做 SSR(server side render)。

很明显,SSR 渲染出画面的速度会很快,因为不需要执行 JS ,而是直接解析 html。因此,app 里嵌的页面基本都用 SSR,这样体验会更好。而且低端机执行 JS 是可能很慢的,要是 CSR,那页面可能会有很长一段白屏时间。

此外,SSR 是直接返回了 html,这样搜索引擎的爬虫就能从中抓取到具体的内容,就会给更高的搜索权重,也就是更有利于 SEO (search engine optimize)。

在 app 里嵌的页面、搜索引擎排名优化这两种场景下,我们都要做 SSR。

知道了 SSR 是什么和为什么要做 SSR,那如何实现 SSR 呢?

SSR 实现原理

我们知道 vue 是通过 template 描述页面结构,而 react 是通过 jsx,但不管是 template 还是 jsx,编译后都会产生 render function,然后执行产生 vdom。

vdom 在浏览器里会通过 dom api 增删改 dom 来完成 CSR,在服务端会通过拼接字符串来完成 SSR。

图片

vdom 是一个树形结构,那么 SSR 就是遍历这棵树,拼接字符串的过程。

图片

看到这张图,不知你有没有想起编译的 generate 阶段也是这样的拼接字符串的过程:

图片

没错,SSR 中 vdom 打印成字符串,和编译中 AST 打印成字符串的逻辑确实是一样的。

口说无凭,我们来看下两者的源码再下结论。

Vue SSR 的渲染流程

vue 提供了 vue-server-renderer 这个包用于 SSR,它的作用就是把 Vue 组件渲染成字符串。

它提供了 createBundleRenderer 的 api:

const bundle = fs.readFileSync(resolve('./dist/server-bundle.js'), 'utf-8');

createBundleRenderer(bundle)

这个 bundle 就是 webpack 编译产生的目标代码:

图片

可能你会问,为啥要等 webpack 把代码编译成 bundle 才去渲染啊?

因为像 esm 的模块语法、像 ts、sass 等语法都不是 node 支持的呀,要先把代码编译打包成 bundle,这样才能在 node 里面跑。

这也是为啥提供的 api 叫做 createBundleRenderer。

创建好 renderer 之后,调用 renderToStream 方法,就开始执行渲染了。

当然,也可以调用 renderToString,这俩 api 的区别是一个是边渲染边返回内容,一个是完全渲染完再返回内容。

图片

渲染第一步,自然是要把传入的 bundle 给执行了:

图片

这里 runInVm 就是执行 bundle 那段字符串的代码,这是基于 node 提供的 vm 包的 api 实现的:

图片

通过 vm.runInContext 可以在某个上下文中执行一段代码。

执行之后,返回的就是 Vue 的实例:

图片

注意,这里是在 node 环境里创建的 Vue 实例,所以没有 dom api,不能操作 dom,但可以打印成字符串:

图片

这里 render 的实现就是拼接字符串:

图片

这样遍历完一遍 vdom,就拼接好了最终的 html:

图片

把这段 html 返回给浏览器即可。这样我们就实现了 Vue 的 SSR!

小结一下 Vue SSR 的流程:

vue-server-renderer 包提供了 createBundleRenderer 的 api,可以传入编译打包后的 bundle 代码来创建一个 renderer。renderer 有 renderToString 和 renderToStream 的 api。内部会通过 vm.runInContext 来执行 bundle 的代码,产生 Vue 实例,之后把 Vue 实例的 vdom 渲染成 html 字符串。返回这个 html 字符串就实现了 SSR。

当然,实际做 SSR 的时候,我们不会直接用 vue-server-renderer,而是会用封装了一层的 nuxt.js,因为它对路由等做了处理,并且对工具链的封装也很好,开箱即用。

到了这里,我们可以说 SSR 就是遍历 vdom 拼接字符串的过程了。

接下来再看下编译中的 generate 阶段:

编译流程

前端领域的编译基本都是源码转源码,所以流程都差不多,都是 parse、transform、generate 这三步:

图片

parse 阶段把源码转为 AST(抽象语法树),然后 transform 阶段会对 AST 做各种增删改,generate 阶段会把修改后的 AST 递归打印成字符串。

这里的 generate 阶段就像 SSR 的 render 一样,也是个拼接字符串的过程:

比如 babel 的 generate 的实现是这样的:

打印 while 节点:

图片

打印 condition 节点:

图片

递归遍历 AST,打印每个节点,拼接字符串,就能产生目标代码。

所以说,SSR 的 vdom render 和前端编译的 AST generate 是一样的逻辑,都是拼接字符串。

当然,也是有很多不同的地方的,比如 SSR 的 vdom 是动态执行 render function 产生的,而编译中的 AST 是从源码中静态编译产生的。只是代码生成的拼接字符串的逻辑一样。

总结

SSR 渲染首屏画面速度快,而且利于搜索引擎的抓取,所以在 app 里嵌的页面、SEO 这两种场景下,我们都会做 SSR。

SSR 的原理就是把 vdom 打印成 字符串,这和前端编译中的 generate 阶段很类似。

我们看了 Vue 的 vue-server-render 包的源码,它提供了 createBundleRenderer 的 api,传入编译打包后的 bundle 代码,通过 vm 执行它,然后把产生的 Vue 实例的 vdom 打印成 html 字符串,就实现了 SSR。

我们也看了 babel generator 的源码,它提供了每种节点的打印逻辑,递归遍历 AST,拼接字符串,就能产生目标代码。

虽然 SSR 和前端编译在流程上和目的上都不同,但是在生成代码这一点上是一样的,都是把树形结构打印成字符串。

  • 男人对你做这几件事才是真的爱你(男人在这些时候帮你的忙)
  • 2024-09-30男人在这些时候帮你的忙总有人说男女之间没有纯洁的友谊,想要知道他对你有没有感觉,是不是想要做你的男朋友,看的他是否会帮你的忙就知道了不要在不确定的情况下就直接问他,如果你冒失地主动问出口,反而会让你在他的心目中的期待值降低。
  • 敏感肌起干皮用什么护肤品(别再乱用护肤品了)
  • 2024-09-30别再乱用护肤品了大家好,我是老全,一个专注于护肤品成份分析的男生,今天我们要分享的是关于干皮和敏感肌的问题,干皮和敏感肌算是近几年比较常见的肌肤问题,他和油皮有着本质的区别,油皮是由于皮肤分泌油脂过多造成的,而油脂是。
  • 礼乐制是什么(什么是礼乐制度)
  • 2024-09-30什么是礼乐制度礼乐制度是以乐从属礼的思想制度以“礼”来区别宗法远近等级秩序,同时又以“乐”来和同共融“礼”的等级秩序,两者相辅相成在统治阶级内部所设定的等级具体表现为“天子八佾,诸公六,诸侯四”古代舞队的行列,八人。
  • 天麻种植技术及产量(天麻生物学特性及林下栽培技术)
  • 2024-09-30天麻生物学特性及林下栽培技术天麻生物学特性及林下栽培技术1生物学特性天麻依附蜜环菌分解养分生长,而蜜环菌为白蘑科蜜环菌属一种兼性寄生真菌,发育分为菌丝体和子实体菌丝体以菌丝和菌索两种形态存在,常寄生或腐生于树干和树根的组织内,导。
  • 氨纶是什么面料优缺点(氨纶有哪些优点和缺点)
  • 2024-09-30氨纶有哪些优点和缺点氨纶是一种弹性纤维,学名聚氨酯纤维它具有高度弹性,能够拉长6~7倍,但随张力的消失能迅速恢复到初始状态,其分子结构为一个像链状的、柔软及可伸长性的聚氨基甲酸酯,通过与硬链段连接在一起而增强其特性氨纶优。
  • 锂电池和铅酸电池有啥区别(铅酸电池和锂电池的区别)
  • 2024-09-30铅酸电池和锂电池的区别1、使用寿命不同铅酸电池的使用寿命一般在2年左右;锂电池耐用性较强,使用寿命一般在4-5年2、充放电循环次数不同铅酸电池一般完全充放电为400次以内,有记忆;而锂电池完全充放电为500次,且无记忆3、。
  • 斗罗大陆肖战吃瓜二人组(斗罗大陆被官媒力挺)
  • 2024-09-30斗罗大陆被官媒力挺如何验证一个明星的火热程度?答案是看收视率就知道了这几天由肖战和吴宣仪主演的剧版《斗罗大陆》正在热播,《斗罗大陆》是根据唐家三少的经典同名玄幻小说改编,一直以来拥有广泛的群众基础而凭借《陈情令》魏无羡。
  • dnf官方有什么奖励(DNF:5000天纪念奖励汇总)
  • 2024-09-30DNF:5000天纪念奖励汇总不知不觉地下成​已经有了5000天的历史,策划也为此特意更新了5000天纪念活动(此时不割一波韭菜下次再割还得再等5000天),一起看看都有哪些奖励吧(呸,又是被割的一天)1.5000天时光纪念商店时。
  • 许昕对阵丁宁比赛直播(全运会预赛27日直播团体赛)
  • 2024-09-30全运会预赛27日直播团体赛2021年3月27日全运会预赛进入男女团体赛阶段在单项比赛中也没出战的丁宁、许昕等人也将率队征战团体比赛北京女队在丁宁的带领下,首轮对阵安徽女队安徽女队没有国家队主力,丁宁首秀获胜概率相当大男团上海队。
  • 全国十大门窗一线品牌(十大高端门窗一线品牌)
  • 2024-09-30十大高端门窗一线品牌十大高端门窗一线品牌有哪些?1.阿尔卑斯门窗、2.良木道门窗、3.欧哲门窗、4.旭格门窗、5.皇派门窗、6.罗兰西尼门窗、7.阿鲁克门窗、8.贝克洛门窗、9.希洛门窗、10.派雅门窗十大高端门窗一线品。
  • 亚马逊养号的正确方法(亚马逊养号攻略)
  • 2024-09-30亚马逊养号攻略在亚马逊,我们知道无论是注册卖家号还是买家号,都要求有收件地址和绑定一张真实有效且可以使用的信用卡信用卡五花八门种类繁多,但不是所有的卡都合适而收货地址有很多新手卖家也不知道该怎么填写!下面就分别来介。
  • 不刷机怎么打开密码锁(重置锁屏密码操作方法)
  • 2024-09-30重置锁屏密码操作方法如果开启了【查找手机】功能,可进入官网云服务;登录账号,查找手机-锁屏/锁死-输入新的数字或图案密码-点击锁定,该密码即新的锁屏密码;手机若未开启查找手机功能,需携带手机及购机凭证前往当地手机客户服务。