avalon2为了提高性能,采用全新的架构,四层架构,其中一层为虚拟DOM。

虚拟DOM的一个好处是能大大提高性能,另一个好处是能过错整描述我们的页面结构。因此在非浏览器环境下,虚拟DOM也能正常运行。并且avalon2自一开始,就努力隔离DOM API。基于这两点,avalon2可以原封不动地运行于nodejs中,进行定义VM,渲染视图等操作。

  1. 客户端上,虚拟DOM通过vm.$render方法渲染到页面中

  2. 服务端上,虚拟DOM使用serveRender生成HTML字符串

与react的后端渲染相比,它的使用是非常简单的。React的渲染单位是组件,组件有生命周期,我们在添加一些处理时,都是放在生命周期钩子中(getDefaultProps,getInitialState,componentWillMount,componentDidMount,componentWillUpdate。。。。),而在nodejs,生命周期只能走到componentDidMount之前。用户想后端渲染,需要有针对性地写代码。而avalon2则不需要懂这些,只要保证所有DOM操作在回调中就行了。

react的后端渲染有两个方法,ReactDOMServer.renderToString 和 ReactDOMServer.renderToStaticMarkup。renderToString带着uuid,为了前端只进行绑定事件,不再生成DOM,但缺点是让页面体积变大很多。而renderToStaticMarkup只能输入不带交互的静态页面。

而avalon只有一个方法,它输出的页面没有ms-xxx,:xxx这些绑定属性,因此相当于输出静态页面。为了实现绑定属性功能,如果将模板函数或已经生成好的事件传过去,想必体积太大。因此avalon将原始页面的很少一部分压缩传过去。即便你没有用html-minify这些工具,avalon也会做去空白节点处理!

因此从生成页面速度,与传输体积上,avalon的后端渲染都比react优秀不少。

与传统后端渲染相比,即JSP,PHP方案,主要好处是,模板的控制台掌握在我们前端手中。不要痛苦成为套页面的工具。avalon对切图人员交给我们的页面,所做修改是很少的,就是加一些绑定属性。

与近年流行前端模板渲染方案相比,即后端出数据,前端在script标签,textarea标签里写模板,主要好处是SEO!前端模板是无法搞定SEO,并且还有"首屏乱码"问题,这些在ng, avalon1, vue1 也有这问题,需要ng-cloak 等东西做遮丑布! 有了后端渲染就没有这问题了。

好了,我们看如何做。为简单起见,本文使用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的方案及早期百度,腾讯基于它们的私有框架的实践。

  1. https://segmentfault.com/a/1190000004135256
  2. https://segmentfault.com/a/1190000005679938
  3. https://segmentfault.com/a/1190000005641012

avalon2的后端渲染实践的更多相关文章

  1. 基于 koajs 的前后端分离实践

    一.什么是前后端分离? 前后端分离的概念和优势在这里不再赘述,有兴趣的同学可以看各个前辈们一系列总结和讨论: 系列文章:前后端分离的思考与实践(1-6) slider: 淘宝前后端分离实践 知乎提问: ...

  2. [转]谈谈前端渲染 VS 后端渲染

    首先,预编译跟前后端没有关系,预编译一样可以用于后端渲染. 看看下面的测试时间,单位: ms 模板字符串: var s = '{{#datas}}{{name}} abcdefg {{type}} { ...

  3. 后端渲染html、前端模板渲染html,jquery的html

    作者:赵魏璇链接:https://www.zhihu.com/question/28725977/answer/116177149来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  4. 理解Web路由(浅谈前后端路由与前后端渲染)

    1.什么是路由? 在Web开发过程中,经常会遇到『路由』的概念.那么,到底什么是路由?简单来说,路由就是URL到函数的映射. 路由的概念最开始是由后端提出来的,在以前用模板引擎开发页面的时候,是使用路 ...

  5. 后端渲染神器!Dust

    Dust一个适用于浏览器与node的异步模板框架. 先上实例 后端模板: {@inject api="http://api.myserver.com/get_message"} & ...

  6. Nuxt.js服务端渲染实践,从开发到部署

    感悟 经过几个周六周日的尝试,终于解决了服务端渲染中的常见问题,当SEO不在是问题的时候,或许才是我们搞前端的真正的春天,其中也遇到了一些小坑,Nuxt.js官方还是很给力的,提issue后很积极的给 ...

  7. 后端开发实践——Spring Boot项目模板

    在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...

  8. 后端开发实践系列之三——事件驱动架构(EDA)编码实践

    在本系列的前两篇文章中,笔者分别讲到了后端项目的代码模板和DDD编码实践,在本文中,我将继续以编码实践的方式分享如何落地事件驱动架构. 单纯地讲事件驱动架构(Event Driven Architec ...

  9. 后端开发实践:Spring Boot项目模板

    在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...

随机推荐

  1. windows调试器尝鲜

    曾几何时,我也下载过看雪论坛精华看的津津有味.可惜一直没有动手去调试,学到的x86汇编指令也忘得差不多了.最近将老机器的T4200 CPU换成了更省电,温度更低的P8800,为了支援新的VT虚拟化,特 ...

  2. 2015GitWebRTC编译实录10

    2015.07.20 rtc_p2p编译通过[879/1600 ] CXX obj /webrtc/p2p/client/rtc_p2p.httpportallocator.o[880/1600 ] ...

  3. Quartz在Spring中动态设置cronExpression (spring设置动态定时任务)

    什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定).      这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户 ...

  4. 该应用的登录功能版本较旧,无法使用QQ账号登录,请升级到最新版本,如果还无法解决,请联系开发者升级。(错误码:100044)

    该原因应该是你的应用数据签名更改的原因 解决步骤已经写到我的公众号,二维码在下面. 欢迎观看我的CSDN学院课程,地址:http://edu.csdn.net/course/detail/2877 本 ...

  5. odoo.cli.main()指的是哪里?OpenERP的第二根线头儿

    接上回,odoo-bin中调用了odoo.cli.main(),去哪儿找? cli目录容易找 跟随__init__.py的脚步 import logging import sys import os ...

  6. C++资料收集&整理

    类别 地址 ZLib c++ zlib(qt)压缩与解压缩 STL STL学习之map容器(2)_insert Basic std::nothrow new (nothrow) T() 的原理 C++ ...

  7. ASP.NET MVC : Action过滤器(Filtering)

    http://www.cnblogs.com/QLeelulu/archive/2008/03/21/1117092.html ASP.NET MVC : Action过滤器(Filtering) 相 ...

  8. linux cpu性能测试

    sysbench --test=cpu --cpu-max-prime=20000000 run --num-threads=4 mpstat -P ALL 1 1000000

  9. Apache Shiro系列教程之二:十分钟上手Shiro

    在本教程中,我们会写一个简单的.仅仅输出一些内容命令行程序,从而对Shiro有一个大体的感觉. 一.准备工作 本教程需要Java1.5+,并且我们用Maven生成项目,当然Maven不是必须的,你也可 ...

  10. Excel中如何提取字符串中的数字

    取字符串中的数字,假如数据在A列,提取公式为 =LOOKUP(9^9,--MID(A1,MIN(FIND({1,2,3,4,5,6,7,8,9,0},A1&5^19)),ROW($1:$99) ...