初识前端模板

标签: JavaScript 前端技术 | 发表时间:2011-07-11 17:26 | 作者:yaya slackware
出处:http://www.baiduux.com/blog

总述

“模板”这个词,可能很多人第一印象是后端的技术(Smarty,Velocity等),但本文要讲的却不是后端的概念,而是前端开发中所使用到的一种技术,也就是“前端模板”技术。

模板的工作原理可以简单地分成两个步骤:模板解析(翻译)和数据渲染。这两个步骤可分别部署在前端或后端来执行。如果都放在后端执行,则是像Smarty这样的后端模板,而如果都放在前端来执行,则是我们要探讨的前端模板。

问题

随着前端交互的复杂性不变提升,无刷新页面数据传输与渲染越发地频繁化,我们发现传统的前端开发方式在ajax数据渲染等方面存在着一个主要问题:繁琐的数据渲染。当前端从后台通过ajax等方式或许到数据后,如果要将这个数据渲染到指定的dom元素中,则需要进行各种字符串拼接工作或者一系列创建元素的工作,还不论细节的问题(单引号双引号问题等),不管是哪一种形式,都是繁琐且费时的。同时,在可读性与维护性上也存在问题。试想,各种循环操作的字符串拼接,元素创建插入,在需要修改时,都需要重新花费不少时间与精力。那有什么方法可以解决这个问题呢?

原理

当我们在JSP中写<ul><li><%= name %></li></ul>的时候,其实就是在应用模板,在后台这句话会被转换成out.print(“<ul><li>”+name+”</li></ul>”)。模板的数据渲染就是把模板中的占位符(这里是”name”),替换成传入的值(比如替换成”yaya”)。而在前端开发中,这种方式依然具有很高实用价值。前端模板的核心是前端模板引擎,引擎将前端的模板语言转换成浏览器可以解析的html语言。当转换成功后,便可以很方便地将这段html代码放到我们希望的地方去。



比如我们可以写一段循环的li标签的前端模板语言。通过前端模板引擎转换后成本一连串得li标签的html语言。这时候就可以直接采用innerHTML方法把html代码插入到ul对象中,那么就完成了生成ul列表的功能。

初识

前端的模板核心是模板解析引擎,而解析引擎的主要作用是将模板语言转换成html/xml格式。不同的前端模板有着不同的模板语言,解析引擎因此也各不相同。让我们先来认识几款前端模板,了解下它们各自的模板语言。

Yaya Template是一款轻量级的模板引擎,采用原生javascript语法,具有易学易用等特点。我们来看一段用Yaya Template渲染列表数据的实例:

模板语言(通用过for循环,输出“这是第n列”的li列表)


for(var i=0;i<list.length;i++){

{$ <li>这是第 {% i %} 列:{% list[i] %}</li> $}

}


有了模板语言后,我们只需要将数据“打入”模板语言中的”list”,就可以生成我们想要的html/xml格式了。如上例,我们只需要得到这个模板语言进行翻译,并调用对应的render方法,


var list = [“红桃”,”方块”,”梅花”,”黑桃”];

var html = YayaTemplate(templateText).render({list:list});


这个html则是模板引擎转换成的html/xml语言,在上例中,则为:


<li>这是第0列:红桃</li>

<li>这是第1列:方块</li>

<li>这是第2列:梅花</li>

<li>这是第3列:黑桃</li>


从这个例子中,我们可以发现,{$…$}表示输出的html/xml片段,{%…%}表示输出javascript变量。得到的html,我们可以用直接作为dom的innerHTML或者其他用处。

这便是前端模板,它使得我们不必去处理字符串拼接等问题,用最直观的方式来渲染数据。我们再来看另外一款前端模板EasyTemplate。还是之前的例子,用EasyTemplate模板写法如下:


<#list data as list>

<li>这里是第${list_index} 列:${list}</li>

</#list>


同样,需要将实际数据替换模板变量,这里采用:


var list = [“红桃”,”方块”,”梅花”,”黑桃”];

var html = easyTemplate.render(templateText,list); //templateText指模板语言


EasyTemplate这样的前端模板,是属于自定义模板语言的一种前端模板。我们可以从上例看出,””就是EasyTemplate自定义的循环条件。像这样EasyTemplate 模板一样采用自定义标签的前端模板还有 lite Template:


<c:for var=”item” list=”${list}”>

<li>这里是第${for.index}列:${item}</li>

</c:for>


渲染时采用:


var list = [“红桃”,”方块”,”梅花”,”黑桃”];

var html = liteFunction(templateText,’list’)(list);


好了,我们再来看看jquery作者John Resig所写的一个前端模板jquery template。说真的,它如同jquery一样,短小精悍。还是老例子:


<% for(var i=0;i<list.length;i++){ %>

<li>这是第 <%=i%> 列:<%= list[i] %></li>

<% } %>


渲染采用:


var list = [“红桃”,”方块”,”梅花”,”黑桃”];

var html = tmpl(“templateid”, list);


我们可以看出,Yaya Templatejquery template在模板语言的写法上正好相反。前者将输出html语言做特殊标记{$…$},而后者对javascript语言做特殊标记。这两种模板已经使得学习成本很低了,而接下来介绍的ace template的写法将更加简单易懂。


for(var i=0;i<list.length;i++){

<li>这是第 #{ i } 列:#{ list[i] }</li>

}


渲染采用:


var list = [“红桃”,”方块”,”梅花”,”黑桃”];

var html = AceTemplate.format(“templateid”, {list:list});


ace template采用了html与js语言直接混搭的风格,在两者间可以直接的书写,不用添加任何的标志用以区分不同的语言。而在html语言里面,使用js变量则采用#{}的方式输出。ace template之所以可以兼容html与js混合写法,是通过按行解析来实现的。所以,如果代码能够保证html语言与js按行划分,这样的用法其实是很方便的。并且ace template值得说明的一点是支持自动编码防止xss漏洞,通过#{}渲染出来的javascript变量,已经经过了编码处理,这一点是很方便的。而对于不需要这个功能,需要原文输出的时候,ace template也提供了!#{}方法来满足这种需求。

通过上面对五个前端模板的简单介绍,我们可以了解到不同前端模板的各种形态,这包括写法与用法等直观印象。但我们知道,前端模板的核心是代码的转换,这肯定是需要转换时间的,那就以上五个不同的前端模板,性能上会有怎样不同的表现呢。

性能

前端模板语言到html/xml语言,是通过模板引擎进行翻译的。而模板引擎的翻译性能在某种程度上决定了前端模板解决方案的可行性的高低。上诉五种前端模板,各自的性能会是怎么样的,我们对它们进行测试。分别对Yaya TemplateEasyTemplatejquery template ace templatelite template部署前端模板做同样的操作,比较模板引擎翻译时间代价。

各自的模板代码如下:

Yaya Templat

for (var i=0;i<list.length;i++){

if (i<100){

{$<li>小于100 这里是第{%i%} 列:{%list[i]%}</li>$}

}

else{

{$<li>不小于100 这里是第{%i%} 列:{%list[i]%}</li>$}

}

}


EasyTemplate

<#list data as list>

<#if (list_index <100)>

<li>小于100 这里是第${list_index} 列:${list}</li>

<#else>

<li>不小于100 这里是第${list_index} 列:${list}</li>

</#if>

</#list>


jquery template

<% for (var i=0;i<list.length;i++){ %>

<% if (i<100) { %>

<li>小于100 这里是第<%=i%>列:<%=list[i]%></li>

<% } else{ %>

<li>不小于100 这里是第<%=i%>列:<%=list[i]%></li>

<% } %>

<% } %>


ace template

for (var i=0;i<list.length;i++){

if (i<100){

<li>小于100 这里是第#{i} 列:#{list[i]}</li>

}

else{

<li>不小于100 这里是第#{i} 列:#{list[i]}</li>

}

}


lite template

<c:for var=”item” list=”${list}”>

<c:if test=”${for.index&lt;100}”>

<li> 100 这里是第 $!{for.index} 列:$!{item}</li>

</c:if>

<c:else>

<li>不小于100 这里是第$!{for.index} 列:$!{item}</li>

</c:else>

</c:for>


然后我们改变list数组里面的元素个数,对各个模板翻译执行的时间进行记录。结果如下(xp+ie6/ie8/firefox/chrome运行环境):

模板翻译时间对比表(第一次翻译并渲染数据 时间单位:毫秒)

List长度

Yaya Template

EasyTemplate

jquery template

ace template

lite template

1

ie6

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

16

15

12

4

ie8

firefox

chrome

10

ie6

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

1

16

15

11

2

ie8

firefox

chrome

100

ie6

0

0

0

0

0

0

0

0

0

0

1

1

0

0

1

0

15

16

10

4

ie8

firefox

chrome

1000

ie6

0

0

1

0

16

16

2

3

16

0

3

2

0

0

2

3

15

15

21

7

ie8

firefox

chrome

10000

ie6

63

16

7

4

78

47

22

26

110

47

27

23

62

62

20

22

78

31

22

15

ie8

firefox

chrome

100000

ie6

672

250

75

90

1719

609

221

304

1203

719

267

308

750

328

203

288

688

250

124

114

ie8

firefox

chrome


通过第一次翻译后,如果前端模板可以缓存翻译后的中间代码,或者可以返回构建中间代码的函数,那么再次渲染数据的时候,就不需要再翻译。这样可以极大的缩小渲染数据的时间,提高速度。

综合各种调研数据对比表如下:



Yaya Template

EasyTemplate

jquery template

ace template

lite template

缓存加速

防xss漏洞编码

扩展语法

错误跟踪

代码尺寸(字节)

483

1527

453

2512

91511

兼容

前端模板的兼容性也是一个重要的问题。能够实现用户不同的前端模板需求,将前端模板语言正确翻译成html/xml语言,是优秀的前端模板所需要具备的特点。而通过对以上五种前端模板的测试,并没有发现严重的兼容性问题。但在一些细节上,还是发现了一些问题如下表:

兼容性测试对比表

测试点

Yaya Template

EasyTemplate

jquery template

ace template

lite template

换行空白

通过

空白被省略

通过

通过

通过

空白节点

通过

通过

通过

通过

通过

字符’”/\

通过

通过

\ ‘’未通过

通过

通过

多层嵌套

通过

通过

通过

通过

通过

语法检测

通过

通过

不能通过,在if else语句中常用的形态不能处理。

通过

通过

流程

对于“什么是前端模板,它有什么特性,怎么使用”这样的问题已经通过上面的分析说明给出了答案。但前端模板既然是前端的范畴,就不可能独立存在,而是需要运用到前端开发的流程中的。而采用了前端模版的开发流程与传统的相比又会是怎么样的呢?

上图是传统的开发流程。首先将ui设计图转换成html的页面,其中的数据一般先用模拟数据代替。比如,ui设计有个列表,那么可能开发人员会先建立一些模拟的数据填充到节点中,来开发调整页面样式。最后一步,则将需要动态生成(ajax应用等)的地方,将模拟数据的节点变成空白节点,然后在javascript里面拼装这些html节点的字符串,最后再还原到原节点处(比如用innerHTML插入html)。

上图是一个实例。当列表中的元素需要ajax动态加载的时候,在传统开发中可能按照先开发模拟数据的html页面,再将这些元素拼接成html字符串,之后再进行一系列处理的功能。

那么,它的问题是什么呢?很明显,“不可逆”是最大的问题。当开发者完成了开发,这时候如果需要修改,那么将是很头疼的事。由于是由字符串拼接出来的html片段,想直接修改这些字符串来改变结构或是修改样式什么的将是一个比重新开发一遍还要具有挑战的工作。所以,开发者往往选择再来一遍吧:html的模拟数据页面,然后再拼接字符串。除了“不可逆”,维护性差以及开发成本高都是采用传统方式开发富客户端应用的弊病。

好吧,我们试着改变这个局面。看看下图,采用前端模板开发的新方式,或许会找到某些答案。


“双向可逆”,是的,采用前端模板的开发方式,在开发好展示的html页面后,直接经过简单的修改即可生成html+template 页面,无需再拼接字符串,无需再反复重写展示模拟数据的html页面,一切都变得很轻松。我们来看看代码便知道原因了(以ace template为例)。

如果调用模板引擎,当模板执行数据执行后,直接覆盖parentNode里面的内容。而如果想继续调整html结构等,则不调用模板引擎即可。而原有的调试数据,在需要发布的时候可以直接通过代码编译去掉debug start与debug end之间代码即可(这仅仅是前端模块开发的一种实例,实际开发中可以去掉模拟数据,不用编译)。

展望

前端模板技术其实还有很多的工作要做,比如模板的事件代理,模板的复用性,模板的组件库等等。本文仅对前端模板做了一个大致讲解。相信随着对于前端模板的探索,模板技术会被越来越多得运用的前端开发,特别是富客户端的前端开发中,进一步提高开发效率,为开发人员带来更多的惊喜!

参考资料


1.yaya template http://uloveit.com.cn/template

2.easy template http://www.easyui.org.cn/easyTemplate.html

3.jquery template http://ejohn.org/blog/javascript-micro-templating/

4.ace template http://blog.csdn.net/zswang/article/details/6582563

5.lite template http://code.google.com/p/lite http://firekylin.my.baidu.com


相关 [前端 模板] 推荐:

初识前端模板

- slackware - 百度泛用户体验
“模板”这个词,可能很多人第一印象是后端的技术(Smarty,Velocity等),但本文要讲的却不是后端的概念,而是前端开发中所使用到的一种技术,也就是“前端模板”技术. 模板的工作原理可以简单地分成两个步骤:模板解析(翻译)和数据渲染. 这两个步骤可分别部署在前端或后端来执行. 如果都放在后端执行,则是像Smarty这样的后端模板,而如果都放在前端来执行,则是我们要探讨的前端模板.

前端自动化开发工作流模板

- - 氪星人
每种项目都有自己特定的开发流程、工作流程. 从需求分析、设计、编码、测试、发布,一个整个开发流程中,会根据不同的情况形成自己独特的步骤和流程. 一个工作流的过程不是一开始就固定的,而是随着项目的深入而不断地改进,期间甚至会形成一些工具. 例如当年大神们在Linux写C语言,觉得每次编译好多文件好麻烦,就发明了makefile.

模板方法

- - 博客园_首页
由于前两天刚好用到模板方法这个模式,而且这个模式相对来 比较简单实用,就写写个人的一些认知吧. 大家对宋丹丹和赵本山的小品里有一个很经典的台词一定不会陌生,而且还日常中经常引用:. 《钟点工》中宋丹丹问要把大象装冰箱,总共分几步. 赵本山就懵了,大象那么大,冰箱那么小,怎么才能把大象装冰箱里呢. 答案也很经典:三步:第1步,把冰箱门打开;第2步,把大象装进去;第3步,把冰箱门带上.

前端技术

- - CSDN博客综合推荐文章
随着互联网产业的爆炸式增长,与之伴生的Web前端技术也在历经洗礼和蜕变. 尤其是近几年随着移动终端的发展,越来越多的人开始投身或转行至新领域,这更为当今的IT产业注入了新的活力. 尽管Web前端技术诞生至今时日并不长,但随着Web技术的逐渐深入,今后将会在以下几方面发力. JavaScript的兄弟们.

Bootstrap,网站模板,bootstrap模板

- - CSDN博客Web前端推荐文章
日期:2013-3-31  来源: GBin1.com. Charisma是一套全功能的,免费,会员质量的响应式HTML5管理员界面模板,基于 "Bootstrap",拥有了9套不同的主题颜色内容,可以满足你的不同需要. 完全响应式,针对了移动设备和触摸设备优化. 基于bootstrap,同时也支持jQuery UI.

CSS Media Queries 模板

- - blog.moocss.com
CSS Media Queries 模板. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60.

Eclipse注释模板

- - ITeye博客
Eclipse注释模板:Window->Preference->Java->Code Style->Code Template. (1)Comments-Types 类注释. * @author 你的名字. * @Version 版本. * @ModifiedBy 修改人. * @Copyright 公司名称.

Web前端优化

- - JavaScript - Web前端 - ITeye博客
优点:直接使用浏览器内存的缓存数据,减少网站后台压力,用户体验(速度)好. 缺点:对于时时变化的动态页面,这种情况就不能容忍了,因为每次访问的都是第一次访问的内容,这样即使所请求的页面已经变化了,用户也不可能知道,所以此场景必须要消除这种缓存的影响. 延迟加载,将资源延迟到需要的时候的加载,例如detail页面,相关产品推荐,当用户浏览更多的信息往下拉动滚动时,才进行加载,异步加载可以大幅减少对后端资源的使用,在需要的时候加载,是资源合理使用常用的方式,但是也带来一个问题,当往下拉才去加载,如果性能不够好,用户的体验其实是不好的,“菊花”转动的时间会比较长,同时异步加载对前端性能的作用也是非常明显的,渲染的节点数量大幅减少.

Web 前端测试

- - Web前端 - ITeye博客
Web 网站测试流程和方法(转载). 进行正式测试之前,应先确定如何开展测试,不可盲目的测试. 一般网站的测试,应按以下流程来进行:. 1)使用HTML Link Validator将网站中的错误链接找出来;. 2)测试的顺序为:自顶向下、从左到右;. 3)查看页面title是否正确. (不只首页,所有页面都要查看);.

前端xss攻击

- - SegmentFault 最新的文章
实习的时候在项目中有接触过关于xss攻击的内容,并且使用了项目组中推荐的一些常用的防xss攻击的方法对项目进行了防攻击的完善. 但一直没有时间深入了解这东西,在此,做一个简单的梳理. xss跨站脚本攻击(Cross Site Scripting),是一种经常出现在web应用中的计算机安全漏洞,它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入的恶意html代码会被执行,从而达到恶意用户的特殊目的.