avalon2的後端渲染實踐

avalon2爲了提升性能,採用全新的架構,四層架構,其中一層爲虛擬DOM。javascript

clipboard.png

虛擬DOM的一個好處是能大大提升性能,另外一個好處是能過錯整描述咱們的頁面結構。所以在非瀏覽器環境下,虛擬DOM也能正常運行。而且avalon2自一開始,就努力隔離DOM API。基於這兩點,avalon2能夠原封不動地運行於nodejs中,進行定義VM,渲染視圖等操做。html

圖片描述

  1. 客戶端上,虛擬DOM經過vm.$render方法渲染到頁面中前端

  2. 服務端上,虛擬DOM使用serveRender生成HTML字符串vue

與react的後端渲染相比,它的使用是很是簡單的。React的渲染單位是組件,組件有生命週期,咱們在添加一些處理時,都是放在生命週期鉤子中(getDefaultProps,getInitialState,componentWillMount,componentDidMount,componentWillUpdate。。。。),而在nodejs,生命週期只能走到componentDidMount以前。用戶想後端渲染,須要有針對性地寫代碼。而avalon2則不須要懂這些,只要保證全部DOM操做在回調中就好了。java

react的後端渲染有兩個方法,ReactDOMServer.renderToString 和 ReactDOMServer.renderToStaticMarkup。renderToString帶着uuid,爲了前端只進行綁定事件,再也不生成DOM,但缺點是讓頁面體積變大不少。而renderToStaticMarkup只能輸入不帶交互的靜態頁面。node

而avalon只有一個方法,它輸出的頁面沒有ms-xxx,:xxx這些綁定屬性,所以至關於輸出靜態頁面。爲了實現綁定屬性功能,若是將模板函數或已經生成好的事件傳過去,想必體積太大。所以avalon將原始頁面的不多一部分壓縮傳過去。即使你沒有用html-minify這些工具,avalon也會作去空白節點處理!react

所以從生成頁面速度,與傳輸體積上,avalon的後端渲染都比react優秀很多。webpack

與傳統後端渲染相比,即JSP,PHP方案,主要好處是,模板的控制檯掌握在咱們前端手中。不要痛苦成爲套頁面的工具。avalon對切圖人員交給咱們的頁面,所作修改是不多的,就是加一些綁定屬性。git

與近年流行前端模板渲染方案相比,即後端出數據,前端在script標籤,textarea標籤裏寫模板,主要好處是SEO!前端模板是沒法搞定SEO,而且還有"首屏亂碼"問題,這些在ng, avalon1, vue1 也有這問題,須要ng-cloak 等東西作遮醜布! 有了後端渲染就沒有這問題了。es6

好了,咱們看如何作。爲簡單起見,本文使用koa2作後端框架。koa2是使用es7的async function處理異步,今後告別異步地獄與那些深澀難懂的generators。

但就算最新的nodejs6也不支持async function,不過不要緊,咱們可使用babel。至於如何用,後面直接給出一個例子。如今咱們看一下一些通用的步驟,熟悉了它,你能夠將avalon用於koa1, express及其餘nodejs框架。

  1. 引入最新版 avalon 這裏用avalon.modern體積少些

  2. 引入avalon倉庫下的serve下的文件serveRender.js

  3. 引入你定義VM的文件 (全部DOM操做要在回調裏進行,不要出現 window, document, 方便能在nodejs環境中運行) 對你的VM使用webpack進行打包 (目的是處理module.exports, require)

var vm = avalon.define({
  $id: "test",
  aaa: '222'
})

module.exports = vm //這裏必須使用module.exports,而不是es6 module
  1. 引入你該頁面的模板(就是一個普通的HTML文件片斷,裏面須要用ms-controller,指向你剛纔的VM.$id)

  2. 將VM與模板放進serveRender方法,獲得一個對象,裏面包含渲染好的HTML(A) 及 一個包括全部模板的對象(B)

  3. 建立一個script標籤, 裏面定義一個avalon.serverTemplates對象, 將B對象賦給它

  4. 將上面的標籤與A頁面, 賦給ctx.body發往前端(或其餘能夠放送到前端的方法裏面去)

//1. 引入avalon
var vm = require('./src/avalon')
//2. 引入avalon的後端渲染器
var serveRender = require('./dist/serverRender')
//3. 當前頁面VM
var vm = require('./src/vm')
//4. 當前頁面模板
var test = fs.readFileSync('./src/aaa.html', 'utf-8');

//5. 
var obj = serveRender(vm, test)

//6. 
var files = JSON.stringify(obj.templates)
var script = '<script src="./avalon.js"><\/script>' +
        '<script> avalon.serverTemplates= ' + files + '<\/script>' +
        '<script src="./test.js"><\/script>'
//7. render
app.use(async function(ctx){
     await (ctx.body = script + obj.html)
})

這些我已經作成一個例子,放到GITHUB中,你們能夠下回來看。

這是後端返回前端的源碼,你們能夠作得更漂亮些,把head, body, html等標籤補上。不過就算你不寫,瀏覽器也會幫你補上的。
圖片描述
這是效果圖!
圖片描述

有了後端渲染,咱們就能夠加快首屏的渲染速度與SEO。 而且咱們能夠實現先後同構, 先後端共用一套模型(VM),一套驗證代碼,一套模板!!!作ABTest,埋點等也測試了!後端的一些部分也掌握在咱們前端手中,咱們的價值就愈來愈大,工資天然也上去了!

有關後端渲染的話題,你們也能夠看一下react的方案及早期百度,騰訊基於它們的私有框架的實踐。

https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
https://segmentfault.com/a/11...

相關文章
相關標籤/搜索