ssr源代码(SSR和前端编译在这点上是一样的)
ssr源代码(SSR和前端编译在这点上是一样的)
2024-11-21 10:59:11  作者:俄式爷们儿  网址:https://m.xinb2b.cn/know/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 和前端编译在流程上和目的上都不同,但是在生成代码这一点上是一样的,都是把树形结构打印成字符串。

  • 12306购票退票新规(12306买票退票有新变化)
  • 2024-11-2212306买票退票有新变化近期买火车票的小伙伴请注意为适应疫情防控条件下旅客出行规律铁路部门改进了↓↓售票和退改签服务措施↓↓铁路部门将根据疫情防控要求和客流变化适时调配运力不断改进服务举措努力提升广大旅客出行体验请广大旅客及。
  • 冷落男人的三种方式(冷落男人是有窍门的)
  • 2024-11-22冷落男人是有窍门的我们都听说过,爱情里需要适时去冷一冷对方,不能一直保持高涨的热情但是,很多人冷着冷着,没把人吸引过来,反而把感情给冷没了其实,所谓的“冷落”,是有技巧的对于恋爱中的情侣,如果这种“冷落”超过24小时,。
  • 我的世界別墅教程(我的世界怎么造别墅?)
  • 2024-11-22我的世界怎么造别墅?首先我们打开我的世界游戏,进入游戏之后,首先要为别墅建筑找好地方,选址一定要足够宽阔,而且周围没有别的建筑遮挡附近最好有山有水,这样风景秀丽选好别墅的地址之后,我们开始准备材料,准备的材料包括金色合欢。
  • 如何做好企业营销推广(企业为什么要做营销推广)
  • 2024-11-22企业为什么要做营销推广营销是什么?营销是什么?顾名思义,营销就是对销售的经营而经营销售,就是让销售带上系统营销和品牌营销的印记,不仅要把东西卖出去,还要把名声打出去,营销的真正目的,就是充分挖掘产品价值,然后将这份价值与用。
  • 如何用名字写一首儿歌 小学生儿歌选择题
  • 2024-11-22如何用名字写一首儿歌 小学生儿歌选择题  我记得上学的时候,我最喜欢的试卷类型题是“选择题”,不用写字,用排除法做对的概率很大但前段时间,一位家长在朋友圈晒出自己家孩子的语文试卷“选择题”不看不知道,一看吓一跳,原来选择题也可以自创答案?。
  • 壁纸史莱克七怪戴沐白(史莱克七怪男神cos)
  • 2024-11-22史莱克七怪男神cos众所周知,史莱克七怪就是一群俊男靓女组成的天才队伍他们不仅实力强,天赋异禀,还有着极高的颜值,自登场以来,有无数coser还原他们在动画中的神级容颜一直以来,很多人关注的都是史莱克三美cos,殊不知市。
  • 最值得购买的简易款雅迪电动车(5款值得买的雅迪电动车)
  • 2024-11-225款值得买的雅迪电动车基于消费者对于电动车选购的痛点,中关村在线电动车频道特意推出系列精品栏目《每周推荐》,该栏目主要针对目前市面上正在热销的新品爆款电动车,从整车性能、特色亮点、极限续航、性价比、颜值等方面进行分析,从而。
  • 999感冒灵的各种包装(999感冒灵推出秋裤了)
  • 2024-11-22999感冒灵推出秋裤了过年期间,999感冒灵又火了一把他们正式宣布进军时尚界,推出了四款“高腰暖心秋裤套装”,分别是不凉少年版、穿久保灵版、养生朋克版和跪舔客户版,无论是名字还是款式,都别具一格,很快成为刷屏级的跨界营销案。
  • 世界上最大的钻石是什么 有多大
  • 2024-11-22世界上最大的钻石是什么 有多大世界上最大的钻石是叫库利南库利南(cullinan)1905年1月21日在南非钻矿发现了无色透明、无任何瑕疵、质地极佳的重达3106克拉的钻石原石,以当时矿长的名字命名为“库利南”由于当时南非属英殖民。
  • 腿以下浮肿是什么原因(是哪里出了问题)
  • 2024-11-22是哪里出了问题人生中,大家都想得到健康的身体,不愿面对任何异常,但是,有时,即使再不愿意去面对,一些情况还是会悄悄地找到自己,说是莫名的病症,并不夸张从腿上来看,健康的双腿应该是强健有力的,然而,有些人却会发现双腿。