成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SSR 和前端編譯,在這點上是一樣的

開發 前端
SSR 渲染首屏畫面速度快,而且利于搜索引擎的抓取,所以在 app 里嵌的頁面、SEO 這兩種場景下,我們都會做 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 和前端編譯在流程上和目的上都不同,但是在生成代碼這一點上是一樣的,都是把樹形結構打印成字符串。

責任編輯:武曉燕 來源: 神光的編程秘籍
相關推薦

2021-12-22 07:31:18

RedisNoSQL數據庫

2011-02-28 10:38:13

Windows 8

2012-03-07 17:24:10

戴爾咨詢

2012-12-20 10:17:32

IT運維

2009-06-12 15:26:02

2018-06-26 11:10:54

UbuntuSUSE紅帽

2015-08-25 09:52:36

云計算云計算產業云計算政策

2020-03-02 10:56:41

辦公電腦疫情

2013-01-11 18:10:56

軟件

2020-05-19 10:02:58

CIOIPD集成產品開發

2023-11-21 09:01:30

2021-12-23 15:11:46

Web 3.0元宇宙Metaverse

2011-03-14 16:51:24

2022-09-26 08:06:24

Go語言

2023-08-09 09:03:25

Typescript工具Jsdoc

2021-06-01 05:50:03

Spring@PostConstrLifecycle

2020-05-28 14:11:41

AI 黑科技人工智能

2015-10-19 12:33:01

華三/新IT

2017-05-25 15:02:46

聯宇益通SD-WAN

2020-11-20 16:42:37

前端開發技術
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一级黄色 | 欧美一级二级视频 | 国产视频2021| 亚洲成人午夜电影 | 国产成人免费视频 | 国产激情一区二区三区 | 一区二区视频 | 国产精品一区二区久久 | 日韩一区欧美一区 | 国产成人精品午夜 | 一区二区三区视频在线 | 精品欧美一区二区三区久久久 | 亚洲综合在线视频 | 成年男女免费视频网站 | 日本人做爰大片免费观看一老师 | 午夜国产| 亚洲欧美精品国产一级在线 | 成人一区二区三区在线观看 | 国内精品99| 国产精品视频久久 | 国产视频h | 亚洲综合色丁香婷婷六月图片 | 久久精品一区二区三区四区 | 亚洲精品永久免费 | 免费午夜视频 | 一本大道久久a久久精二百 国产成人免费在线 | 精品国产一区二区三区久久久蜜月 | 亚洲午夜精品在线观看 | 华丽的挑战在线观看 | 中文字幕一区二区三区乱码在线 | 亚洲社区在线 | 中文字幕在线免费 | 国产9久| 亚洲精品免费观看 | 精品久久久久久久 | ww 255hh 在线观看 | 国产欧美在线观看 | 精品一区二区在线观看 | 精品一区在线 | 欧美性jizz18性欧美 | 国产亚洲精品久久久久久豆腐 |