手把手教你ReactJS和VueJS的服務端渲染
導語: 本文面向沒用過服務端渲染以及沒了解過的同學。主要介紹了服務端渲染的歷史,以及React.js興起以後的同構渲染,並分別給出了React.js和Vue.js 的SSR(Server Side Render)的同構例子。所有程式碼在github中給出,可以直接執行。
服務端渲染其實在10多年前Asp, Java就流行了,那個時候都是通過一個後端的模版實現。後來出現了jQuery等庫和框架之後,各種動態頁面又由後端渲染變成了客戶端渲染。2013年React.js的出現後,同構渲染頁面的思想慢慢的流行起來。 所謂同構渲染就是相同的元件既可以在服務端中渲染也可以在前端渲染。能滿足這個條件的服務端只有node.js。本文主要是講同構渲染,也叫做node直出。
雖然同構的思想出現了三年多,但前段時間在面試過程中問了不了社招和校招的同學,對這個概念很多同學都不太清楚,或者是實踐非常少。原因可能是大家所在公司使用node服務的比較少。沒有很好的實踐平臺。 下面就把這個問題講清楚吧。
先說幾個同構渲染的好處:
1. 首屏效能相比提升非常多。
2. node服務和前端公用一套程式碼
3. SEO, 對搜尋引擎友好
4. 網際網路公司面試題常出
沒有同構渲染,頁面的首屏時間,

用了同構渲染,

對比上面兩個圖, 可以發現SSR最少省了兩次從客戶端請求到服務端的時間,一次請求的來回我們叫做RTT時間(Round-Trip Time),特別是在移動端在3G請求一次RTT時間需要500ms,4G和wifi是100ms。 所以從這裡可以看出服務端渲染在首屏時間上有很大的優化。如果在返回的html中內聯首屏的Css樣式,那麼使用者發起html的一次請求就可以看到首屏的頁面。 是的,只要一個請求。 本文並不是專門講效能優化,所以這裡簡單總結,通常SSR可以讓首屏時間節省大概1.5s到2s。像React.js這種150kb左右(React 16大約106kb), 也不會影響首屏時間。
這裡的dom string就是React.js或者Vue.js提供的方法, 根據資料生成的類似於<div></div>的字串。 實踐起來非常簡單,只需要在node服務呼叫一個方法就可以生成。當然這裡需要使用node服務作為中間層,node服務的好處就不在這裡說了。
下面就挑React.js和Vue.js作為例子,大家可以直接跳到自己常用的框架看對應的例子即可,
以React為例,node服務中路由收到請求時,利用React提供的renderToString方法對元件IndexPage輸出字串body,
router.use('/index.html', function(req, res, next){ let body = ReactDOMServer.renderToString(); console.log(body); res.render("page", { body: body }); });
indexPage元件如下,
import React from 'react'; class App extends React.Component{ render() { return(‘hello React SSR!’); }} export default App;
domString的輸出結果是
hello React SSR!
再把domString插入到模版中返回給瀏覽器就完成node直出了。
完整的程式碼在這裡: ofollow,noindex">https://github.com/blogExample2010/blog/tree/master/ReactSSR
參考Readme.md就可以一步步跑起來。
同樣以Vue.js為例, 官方文件 https://ssr.vuejs.org/zh/basic.html ,利用vue-server-renderer的renderToString方法生成字串插入到模版中。
const renderer =require('vue-server-renderer').createRenderer() router.use('/index.html',function(req, res, next){ renderer.renderToString(IndexPage, (err, body) => { if(err) throw err console.log(body) res.render("page", { body: body }); }) });
body在控制檯輸出:
Hello Vue SSR!
完整的程式碼在這裡: https://github.com/blogExample2010/blog/tree/master/VueSSR
總結,其實同構渲染一點也不復雜,參考上面的程式碼相信完全可以把這部分掌握起來。 node直出對提升首屏效能還是非常明顯的變化。