本文最早发表于本人博客:http://www.gotoli.us/?p=694
最近在捣腾前端的东西,学习了一下前端知识。因这方面的知识太浅薄了,这篇简陋的博客就当抛砖引玉。在Web开发中,前端攻城狮和后端攻城狮是不同的物种,一个追求任何场景下都美丽动人,一个追求巨大压力下举重若轻。但两者又必须密切分工合作,才能使得项目顺利进行。分工的核心在于在哪里渲染页面。不同的渲染位置决定了不同分工模式。
渲染是把数据填充进模板,按模板定制的样式把数据展示出来。如下图所示知乎的例子,图左上方的模板定制了我们看到的样子,其中?表示没有数据,这时将一个用户的数据(图左下方)填充进模板,便得到了我们看到的页面(图右边)。这个过程就是渲染。一共有三种渲染的方式。
<a href="http://www.rustle.us/wp-content/uploads/2015/09/Snip20151011_15.png"></a>
<strong><h3>在服务器端渲染</h3></strong>
浏览器发送请求到服务器端,服务器端处理请求并准备好数据,然后将数据写进前端编写的模板中,从而生成html文件,将生成的html发回给浏览器。这样浏览器上就显示页面了。
<code>
<table class="table">
<tr>
<td>项目名称</td>
<td>组长姓名</td>
</tr>
<% for(var i = 0; i < project.length; i ++){ %><% } %>
<tr>
<td><%= project[i]['project'] %></td>
<td><%= project[i]['leadername'] %></td>
</tr >
<% } %>
</table>
</code>
上面是一个模板。这份模板是一个html文件,其中带有数据绑定命令"<td><%= project[i]['project'] %></td>"。当后端程序整理好数据,在服务器端将数据填充模板,渲染出页面。如下代码所示,app.render(模板,project)语句的意思是,在服务器端将projectdata填充进模板生成页面,并将其发送给浏览器。
<code>
app.get("/show",function(req,res){
projectdata = preparedata();
render(模板,projectdata);
})
</code>
这个模式有一个问题——不能实现部分更新。即使用户点了一个按钮,产生了很细微的数据变动,也需要后端重新渲染整个页面再将页面发往浏览器端。如果页面存在大量的静态的部分,这种方式无疑不是高效的。
同时,前端工程师们需要用模板定义展现形式,后端工程师们需要用模板输出数据。久而久之,模板就会越来越复杂,越来越不可维护。
<strong><h3>在浏览器端渲染</h3></strong>
现在一个趋势是渲染移动到浏览器完成。浏览器端发送请求后从服务器端接受到了模板和 J S代码。浏览器执行接受到的 JS 代码,JS 代码会从服务器请求数据,并将数据填充到模板中。下面的代码在页面加载完之后从接口 /online/projectlang 获取项目语言的数据,并将其写入html页面。
<code>
$(document).ready(function(){
$.ajax({
url:"/online/projectlang",
type:'get',
dataType:'json',
success:function(data){
var list = '';
for(int i = 0 ; i < data.length; i ++){
var item = "<li><a href='#'>" + data[i] + "</a></li>";
list += item;
}
$("#projectlang").append(list);
},
;error:function(xhr, status, error){
console.log("projecthot ajax "+ error);
},
});
})
</code>
这段代码执行的效果如下图所示。
<a href="http://www.rustle.us/wp-content/uploads/2015/09/QQ截图20151012101302.jpg">
利用运行在浏览器端的Javascript语言,前端工程师能够从后端服务器获取数据,进而按照业务逻辑渲染页面。这时候后端工程师只需要开发稳定的 API 提供数据就可以了。这种模式虽然依然是B/S模式,但开发的场景却和C/S模式比较相近。在浏览器端渲染的好处在于前端完全控制了模板,后端只需要开发相应的 API, 分工比较明确。并且支持部分页面更新。同时同一套后端服务可以同时支持不同的展示模式,比如同一套后端服务还可以支持移动开发。
当然啦,浏览器渲染也存在一些问题。其中最大的问题是对 SEO 不友好。搜索引擎的爬虫程序必须像浏览器一样执行 JS 代码才能获得页面的内容,从而提高了爬虫爬取页面的难度。
<strong><h3>大前端模式</h3></strong>
借助神器Node.js,前端工程师终于把磨爪伸进服务器了。Node.js是一个来自老毛子的高性能异步服务器。如果只是一个服务器,Node.js并不出奇。一般服务器需要提供一种编程语言的runtime,方便开发者进行开发。Node.js因为异步的关系选择了异步性能很好的Javascript,就是前端工程师经常在页面上写的那个Javascript。这时前端工程师们一看,呀,这玩意我会呀。因此利用Node.js,前端工程师不再局限在浏览器,可以在服务器写Javascript代码了。这时前端工程师可以按需要,选择在浏览器端或者服务器端完成渲染。这个模式我们可以称之为大前端模式。
大前端模式下,前端工程师有更大的灵活性进行开发,从而可以避免前面两种模式的弊端,发挥他们的长处。但是,世间无十全十美之事,大前端模式也有自己的弊端。前端工程师们被赋予了服务器写代码的能力,也就需要承担服务器编程的责任。能力越大责任也就越大嘛。在服务器写代码,前端工程师必须承担日志、安全和负载均衡等后端工程师才需要承担的责任。大前端攻城狮相当于把前端攻城狮和后端攻城狮两种物种的基因杂揉在一起创造出来的混元体,其稀有程度可想而知。这也就是现在精通Node.js程序员少的原因。
以前第一种模式占主流地位,而现在第二种模式慢慢地受到了大家的关注。至于第三种模式,据我了解,目前只有淘宝一家在进行这方面的尝试。我个人比较喜欢第二种模式。第一种模式太老,第三种模式对工程师要求太高,毕竟前端工程师和后端工程师的技能树差异比较大。但开发领域没有银弹,不同的场景需要选择不同的模型。